使用socket實(shí)現(xiàn)網(wǎng)絡(luò)聊天室和私聊功能
使用socket技術(shù)實(shí)現(xiàn)網(wǎng)絡(luò)聊天室和私聊功能,具體內(nèi)容如下
話不多說先上圖:
1、聊天室群聊頁面
在線用戶的聯(lián)系人列表
socket連接頁面
私聊頁面
項目介紹
與服務(wù)端實(shí)現(xiàn)socket連接:每個客戶端連接到服務(wù)器的時候,服務(wù)器會將每個連接的socket保存在list集合中。
群聊功能:當(dāng)有一個用戶發(fā)送群聊消息給服務(wù)器的時候,服務(wù)器會將所有信息轉(zhuǎn)發(fā)給list列表中的所有已連接的客戶端。
私聊功能:用戶發(fā)送私聊信息給服務(wù)器后,服務(wù)器會向一個目標(biāo)ip發(fā)送消息。
顯示在線聯(lián)系人列表:當(dāng)有新用戶登錄成功的時候,服務(wù)器會將在線聯(lián)系人的信息用json字符串的形式發(fā)送給客戶端,客戶端通過解析json字符串來獲取在線聯(lián)系人的信息。
自定義一個強(qiáng)大的類SocketEvent:客戶端與服務(wù)器通信全部都是通過這個類來保存數(shù)據(jù)的,然后使用fastjson工具來把類對象轉(zhuǎn)換為json字符串來傳輸。
public class SocketEvent { private int type =0; private String msg =""; private String keyIP =""; // 關(guān)鍵IP private String temporaryIP =""; // 臨時IP public SocketEvent() { } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getKeyIP() { return keyIP; } public void setKeyIP(String keyIP) { this.keyIP = keyIP; } public String getTemporaryIP() { return temporaryIP; } public void setTemporaryIP(String temporaryIP) { this.temporaryIP = temporaryIP; } }
type: 標(biāo)志當(dāng)前發(fā)送的信息是什么類型的信息。服務(wù)端和客戶端解 析數(shù)據(jù)就是通過這個它來判斷屬于哪種類型的消息
public static final int CHAT_PRIVATE = 111; // 私聊的指令 public static final int CHAT_GROUP = 222; // 群聊的指令 public static final int SOCKET_SUCCESS = 333; // socket連接成功的指令 public static final int SOCKET_FAIL = 444; // socket連接失敗的指令 public static final int CONNECT_SUCCESS = 666; // socket連接成功的指令 public static final int CONNECT_FAIL = 777; // socket連接失敗的指令 public static final int LOGIN_ARG = 888; // socket接收到標(biāo)志新用戶登錄的指令 public static final int CANCEL_ARG = 999; // socket接收到標(biāo)志用戶注銷的指令 public static final int NEW_CLIENT = 3332; // 新用戶登錄的指令 public static final int ALL_CLIENT = 3432; // 新用戶登錄后接收到所有在線用戶的指令 public static final int SEND_PRIVATE = 5666; // 發(fā)送私聊消息的指令 public static final int SEND_IPlIST = 6666; // 發(fā)送已登錄的用戶IP集合的指令
keyIP:客戶端消息發(fā)起者的ip地址
temperoryIP:臨時的IP地址,如果是type是私聊類型的那么這個ip代表的就是目標(biāo)聯(lián)系人的ip地址
服務(wù)端代碼 (ServerSocket)
1. 接收客戶端的連接
Socket Socketclient = server.accept();
2.開啟線程實(shí)時接收來自客戶端的信息
// 實(shí)時獲取客戶端發(fā)送的數(shù)據(jù) @Override public void run() { try { while (true) { if ((acceptLine = in.readLine()) != null) { System.out.println("<接收到的消息是>" + acceptLine); SocketEvent event = JSON.parseObject(acceptLine, SocketEvent.class); switch (event.getType()) { case UtilFactory.CHAT_GROUP: sendMsgAvoid(event.getKeyIP(), acceptLine); break; case UtilFactory.SEND_PRIVATE: event.setType(UtilFactory.CHAT_PRIVATE); sendMsgTarget(event.getTemporaryIP(), JSON.toJSONString(event)); break; } } } } catch (Exception e) { e.printStackTrace(); } }
3. 向指定ip發(fā)送消息的方法和除了自己ip向其他所有ip發(fā)送消息的方法
// 向指定的ip地址發(fā)送消息 private void sendMsgTarget(String targetIP, String msg) { int num = mList.size(); for (int index = 0; index < num; index++) { Socket mSocket = mList.get(index); String ip = mSocket.getInetAddress().getHostAddress(); if (ip.equals(targetIP)) { PrintWriter pout = null; try { pout = new PrintWriter( new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream(), "UTF-8")), true); pout.println(msg); // 退出方法 return; } catch (IOException e) { e.printStackTrace(); } } } } // 向除了這個ip以外的所有ip發(fā)送 private void sendMsgAvoid(String avoidIP, String msString) { int num = mList.size(); for (int index = 0; index < num; index++) { Socket mSocket = mList.get(index); String ip = mSocket.getInetAddress().getHostAddress(); if (!ip.equals(avoidIP)) { PrintWriter pout = null; try { pout = new PrintWriter( new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream(), "UTF-8")), true); pout.println(msString); } catch (IOException e) { e.printStackTrace(); } } } }
客戶端在mainActivity中接受來自服務(wù)端的所有信息,根據(jù)type來進(jìn)行再次分裝,使用Eventbus將信息發(fā)送給各個fragment來進(jìn)行展示
@Subscribe(threadMode = ThreadMode.MAIN) public void privateChat(SocketEvent event) { switch (event.getType()) { case MyApplication.CHAT_PRIVATE: // 將消息post給私聊聊天室 ChatMessageBean bean = new ChatMessageBean(); bean.setMsg(event.getMsg()); bean.setName(event.getKeyIP()); bean.setType(ChatMessageBean.OTHERS_ARG); EventBus.getDefault().post(bean); break; case MyApplication.SEND_PRIVATE: sendMsg(JSON.toJSONString(event)); break; } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 使用Java和WebSocket實(shí)現(xiàn)網(wǎng)頁聊天室實(shí)例代碼
- Java基于socket實(shí)現(xiàn)簡易聊天室實(shí)例
- 使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
- php socket實(shí)現(xiàn)的聊天室代碼分享
- php+html5基于websocket實(shí)現(xiàn)聊天室的方法
- java實(shí)現(xiàn)一個簡單TCPSocket聊天室功能分享
- Java Socket聊天室編程(一)之利用socket實(shí)現(xiàn)聊天之消息推送
- Spring Boot實(shí)戰(zhàn)之netty-socketio實(shí)現(xiàn)簡單聊天室(給指定用戶推送消息)
- Java Socket聊天室編程(二)之利用socket實(shí)現(xiàn)單聊聊天室
- Python socket C/S結(jié)構(gòu)的聊天室應(yīng)用實(shí)現(xiàn)
相關(guān)文章
Maven中optional和scope元素的使用弄明白了嗎
這篇文章主要介紹了Maven中optional和scope元素的使用弄明白了嗎,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Java設(shè)計模式開發(fā)中使用觀察者模式的實(shí)例教程
這篇文章主要介紹了Java設(shè)計模式開發(fā)中使用觀察者模式的實(shí)例教程,松耦合和邏輯清晰的消息監(jiān)聽是觀察者模式的大特色,需要的朋友可以參考下2016-04-04- 下面小編就為大家?guī)硪黄狫ava創(chuàng)建數(shù)組的幾種方式總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望能給大家?guī)韼椭?/div> 2021-06-06
java中url漢字編碼互相轉(zhuǎn)換實(shí)例
這篇文章介紹了java中url漢字編碼互相轉(zhuǎn)換實(shí)例,有需要的朋友可以參考一下2013-10-10jcl與jul?log4j1?log4j2?logback日志系統(tǒng)機(jī)制及集成原理
這篇文章主要介紹了jcl與jul?log4j1?log4j2?logback的集成原理,Apache?Commons-logging?通用日志框架與日志系統(tǒng)的機(jī)制,有需要的朋友可以借鑒參考下2022-03-03SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解
這篇文章主要為大家介紹了SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12最新評論