赞
踩
1、轮训方式
2、SSE(server-send event)服务器发送事件
3、websocket
websocket 是一种基于TCP 连接上进行全双工通信的协议
websocket对象创建
websocket对象相关事件
websocket 对象提供的方法
Java websocket 应用由一系列的 Endpoint组成。
Endpoint 是一个java对象,代表websocket连接的一段。对于服务端,我们可以视其为处理具体websocket消息的接口。
我们可以通过两种方式定义EndPoint:
编程式,继承类 javax.websocket.Endpoint 并实现其方法
注解式,定义一个pojo,并添加@ServerEndPoint相关注解
服务端如何接收客户端发过来的数据呢?
编程式
通过添加MessageHandler消息处理器来接收消息
注解式
在定义endpoint时,通过@OnMessage 注解指定接收消息的方法
服务器如何推送消息给客户端
发送消息由RemoteEndpoint完成,其实例由Session维护。
通过websocket实现在线聊天室
1) 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2)编写配置类
扫描所有添加 @ServerEndpoint注解的Bean
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
编写配置类,用于获取 HttpSession 对象
public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator { /** * @param sec * @param request 握手请求 * @param response */ @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { // 获取HttpSession对象 HttpSession httpSession = (HttpSession) request.getHttpSession(); // 将 HttpSession对象保存起来 sec.getUserProperties().put(HttpSession.class.getName(), httpSession); } }
在@ServerEndpoint 注解中引入配置器 @ServerEndpoint(value = “/chat”, configurator = GetHttpSessionConfig.class)
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class) @Component public class ChatEndpoint { /** * 使用static * ChatEndpoint是多例的,多个实例共享一个Map对象 */ private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>(); private HttpSession httpSession; @OnOpen public void onOpen(Session session, EndpointConfig endpointConfig) { this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName()); String userName = (String) httpSession.getAttribute("user"); // 1、将我们的session进行保存 onlineUsers.put(userName, session); // 2、广播消息,将登录的用户推送给所有的用户 String message = MessageUtils.getMessage(true, null, userName + "上线"); boardcast(message); // 3、 } /** * 广播消息 */ private void boardcast(String message) { // 遍历 map 集合 Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet(); for (Map.Entry<String, Session> entry : entries) { Session session = entry.getValue(); try { session.getBasicRemote().sendText(message); } catch (IOException e) { // 记录日志 } } } /** * 浏览器发送消息到服务端,该方法会被调用 */ @OnMessage public void onMessage(String message, EndpointConfig endpointConfig) { try { this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName()); String fromName = (String) httpSession.getAttribute("user"); // 将消息推送给指定的用户 message : {"toName":"张三","message":"你好"} ClientMessage message1 = JSON.parseObject(message, ClientMessage.class); String toName = message1.getToName(); Session session = onlineUsers.get(toName); String message2 = MessageUtils.getMessage(false, fromName, message1.getMessage()); session.getBasicRemote().sendText(message2); } catch (IOException e) { throw new RuntimeException(e); } } /** * 当websocket连接断开时,此方法会被处罚 */ @OnClose public void onClose(Session session, EndpointConfig endpointConfig) { // 从在线用户集合中剔除断开连接的用户 this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName()); String userName = (String) httpSession.getAttribute("user"); onlineUsers.remove(userName); // 通知其他用户当前用户下线 String message = MessageUtils.getMessage(true, null, userName + "上线"); boardcast(message); } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。