??领域:Java后端开发
??收录专栏: 系统设计与实战
??个人主页:
??Gitee:https://gitee.com/
个人标签:【后端】【大数据】【前端】【运维】
线上演示地址:http://chat.breez.work
实时通信
(Instant Messaging,简称IM)是一个实时
通信系统,允许两人或多人使用网络实时的传递文字消息
、文件
、语音
与视频交流
。[4]
场景再现:
WebSocket
对象提供了用于创建和管理 WebSocket 连接,以及可以通过该连接发送
和接收数据
的 API。使用 WebSocket() 构造函数来构造一个 WebSocket。[1]
构造函数如下所示:
const webSocket = WebSocket(url[, protocols])
例子如下:
const webSocket = new WebSocket("ws://42.193.120.86:3688/ws/小明/翠花")
1、 webSocket.send()
该函数用于向服务端发送一条消息,例子如下:
webSocket.send("Hello server!");
2、 webSocket.close()
该函数用于关闭客户端与服务端的连接,例子如下:
webSocket.close();
1、webSocket.onopen
该事件用于监听客户端与服务端的连接状态,如果客户端与服务端连接成功
则该事件触发,例子如下:
webSocket.onopen = function(event) {
console.log("连接已经建立,可以进行通信");
};
2、webSocket.onclose
如果服务端与客户端连接断开,那么此事件出发,例子如下:
webSocket.onclose = function(event) {
console.log("连接已经关闭");
};
3、webSocket: message event
该事件用于监听服务端向客户端发送的消息,例子如下:
webSocket.addEventListener('message', function (event) {
console.log('来自服务端的消息:', event.data);
});
4、webSocket:error event
如果客户端与服务端发生错误时,那么此事件将会触发,例子如下:
webSocket.addEventListener('error', function (event) {
console.log('连接出现错误', event);
});
@ServerEndpoint
用于声明一个socket服务,例子如下:
@ServerEndpoint(value = "/ws/{userId}/{targetId}")
几个重要的方法
注解:
@OnOpen
打开连接@OnClose
监听关闭@OnMessage
发送消息@OnError
监听错误
org.springframework.boot
spring-boot-starter-websocket
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
下面的userId
代表发送者
的ID号,target
代表发送目标
ID号。
@Component
@ServerEndpoint(value = "/ws/{userId}/{target}")
public class WebSocketService {
//用于保存连接的用户信息
private static ConcurrentHashMap SESSION = new ConcurrentHashMap<>();
//原子递增递减,用于统计在线用户数
private static AtomicInteger count = new AtomicInteger();
//消息队列,用于保存待发送的信息
private Queue queue = new LinkedBlockingDeque<>();
//onOpen()
//onClose()
//onMessage()
//onError()
}
建立连接之前,判断用户是否已经连接,如果没有连接,那么将用户session信息保存到集合,然后计数器递增。
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
if (!SESSION.containsKey(userId)) {
SESSION.put(userId, session);
count.incrementAndGet();
}
}
关闭连接的时候,将用户session删除和计数器递减。
@OnClose
public void onClose(@PathParam("userId") String userId) {
SESSION.remove(userId);
count.decrementAndGet();
}
发送采用的方法是:session.getBasicRemote().sendText("你好");
@OnMessage
public void onMessage(String message, @PathParam("userId") String userId, @PathParam("target") String target) throws IOException {
queue.add(message);
Session s = SESSION.get(target);
if (s == null) {
Session b = SESSION.get(userId);
b.getBasicRemote().sendText("对方不在线");
} else {
for (int i = 0; i < queue.size(); i++) {
String msg = queue.poll();
Message m = new Message();
m.setUserId(userId);
s.getBasicRemote().sendText(msg);
}
}
}
出现错误,删除用户session信息和计数器递减
@OnError
public void onError(Throwable error, @PathParam("userId") String userId) {
SESSION.remove(userId);
count.decrementAndGet();
error.printStackTrace();
}
本案例中客户端采用Nuxt编写,相关代码如下
运行截图如图所示:
欢迎使用喵喵号聊天
聊一下
运行截图如下:
小明
翠花
我的喵喵号:{{user.userId}}
对方喵喵号:{{user.targetId}}
清空消息
{{m.msg}}
{{m.msg}}
系统消息:{{m.msg}}
发送
??收录专栏:系统设计与实战