使用socket實現(xiàn)網(wǎng)絡(luò)聊天室和私聊功能
使用socket技術(shù)實現(xiàn)網(wǎng)絡(luò)聊天室和私聊功能,具體內(nèi)容如下
話不多說先上圖:
1、聊天室群聊頁面

在線用戶的聯(lián)系人列表

socket連接頁面

私聊頁面

項目介紹
與服務(wù)端實現(xiàn)socket連接:每個客戶端連接到服務(wù)器的時候,服務(wù)器會將每個連接的socket保存在list集合中。
群聊功能:當有一個用戶發(fā)送群聊消息給服務(wù)器的時候,服務(wù)器會將所有信息轉(zhuǎn)發(fā)給list列表中的所有已連接的客戶端。
私聊功能:用戶發(fā)送私聊信息給服務(wù)器后,服務(wù)器會向一個目標ip發(fā)送消息。
顯示在線聯(lián)系人列表:當有新用戶登錄成功的時候,服務(wù)器會將在線聯(lián)系人的信息用json字符串的形式發(fā)送給客戶端,客戶端通過解析json字符串來獲取在線聯(lián)系人的信息。
自定義一個強大的類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: 標志當前發(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接收到標志新用戶登錄的指令 public static final int CANCEL_ARG = 999; // socket接收到標志用戶注銷的指令 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代表的就是目標聯(lián)系人的ip地址
服務(wù)端代碼 (ServerSocket)
1. 接收客戶端的連接
Socket Socketclient = server.accept();
2.開啟線程實時接收來自客戶端的信息
// 實時獲取客戶端發(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來進行再次分裝,使用Eventbus將信息發(fā)送給各個fragment來進行展示
@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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- 使用Java和WebSocket實現(xiàn)網(wǎng)頁聊天室實例代碼
- Java基于socket實現(xiàn)簡易聊天室實例
- 使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
- php socket實現(xiàn)的聊天室代碼分享
- php+html5基于websocket實現(xiàn)聊天室的方法
- java實現(xiàn)一個簡單TCPSocket聊天室功能分享
- Java Socket聊天室編程(一)之利用socket實現(xiàn)聊天之消息推送
- Spring Boot實戰(zhàn)之netty-socketio實現(xiàn)簡單聊天室(給指定用戶推送消息)
- Java Socket聊天室編程(二)之利用socket實現(xiàn)單聊聊天室
- Python socket C/S結(jié)構(gòu)的聊天室應(yīng)用實現(xiàn)
相關(guān)文章
Invalid bound statement(not found):錯誤的解決方案
本文介紹了在開發(fā)Java SpringBoot應(yīng)用程序時出現(xiàn)的"Invalidboundstatement(notfound)"錯誤的原因及解決方法,該錯誤通常與MyBatis或其他持久化框架相關(guān),可能是由于配置錯誤、拼寫錯誤或其他問題引起的,解決方法包括檢查SQL映射文件2025-01-01
SpringBoot 項目使用hutool 工具進行 http 接口調(diào)用的處理方
在實際的開發(fā)過程中一個互聯(lián)網(wǎng)的項目來說 ,有可能會涉及到調(diào)用外部接口的實際業(yè)務(wù)場景,下面通過本文給大家介紹SpringBoot 項目 使用hutool 工具進行 http 接口調(diào)用的處理方法,需要的朋友可以參考下2022-06-06
SpringCloud?Gateway中GatewayFilterChain執(zhí)行流程詳解
Spring?Cloud?Gateway旨在為微服務(wù)架構(gòu)提供一種簡單有效的、統(tǒng)一的?API?路由管理方式。Spring?Cloud?Gateway?作為?Spring?Cloud?生態(tài)系中的網(wǎng)關(guān),它不僅提供統(tǒng)一的路由方式,并且基于?Filter?鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全、監(jiān)控/埋點和限流等2022-10-10

