【267期】SpringBoot如何整合WebSocket实现群聊,一对一聊天_

0分享至

用扫码二维码

分享至好友和朋友圈

点击上方“Java精选”,选择“设为星标”

别问别人为什么,多问自己凭什么!

下方有惊喜,留言必回,有问必答!

每一天进步一点点,是成功的开始...

1.websocket

websocket最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。浏览器和服务器只需要要做一个握手的动作,在建立连接之后,服务器可以主动传送数据给客户端,客户端也可以随时向服务器发送数据。

第一、WebSocket是HTML5中的协议,支持持久连接;而Http协议不支持持久连接。

第二、首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说

HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。

在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。

第三、传统的http请求,其并发能力都是依赖同时发起多个TCP连接访问服务器实现的(因此并发数受限于浏览器允许的并发连接数),而websocket则允许我们在一条ws连接上同时并发多个请求,即在A请求发出后A响应还未到达,就可以继续发出B请求。由于TCP的慢启动特性(新连接速度上来是需要时间的),以及连接本身的握手损耗,都使得websocket协议的这一特性有很大的效率提升。

第四、http协议的头部太大,且每个请求携带的几百上千字节的头部大部分是重复的,很多时候可能响应都远没有请求中的header空间大。如此多无效的内容传递是因为无法利用上一条请求内容,websocket则因为复用长连接而没有这一问题。

第五、当需要实现客户端刷新消息时,传统方案往往通过定时ajax请求实现,实际上对多数用户多数时间下这些请求都是无意义了,并且非常占用资源,websocket资源占用就小很多。

2.在springboot程序当中使用websocket,接下来这套程序能够实现的功能有:

websocket连接:

上线通知:

下线通知:

在线人数统计:

对所有人聊天:

一对一聊天:

第一步:导入websocket的依赖

org.springframework.bootgroupId>spring-boot-starter-websocketartifactId>dependency>

第二步:websocket的配置我

* websocket的配置@Configurationpublic class WebSocketStompConfig{@Beanpublic ServerEndpointExporter serverEndpointExporter()return new ServerEndpointExporter();

@Component@ServerEndpoint("/websocket/{username}")public class WebSocket {private Logger logger = LoggerFactory.getLogger(this.getClass());* 在线人数public static int onlineNumber = 0;* 以用户的姓名为key,WebSocket为对象保存起来private static Map clients = new ConcurrentHashMap();* 会话private Session session;* 用户名称private String username;* 建立连接* @param session@OnOpenpublic void onOpen(@PathParam("username") String username, Session session)onlineNumber++;logger.info("现在来连接的客户id:"+session.getId()+"用户名:"+username);this.username = username;this.session = session;logger.info("有新连接加入! 当前在线人数" + onlineNumber);try {//messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息//先给所有人发送通知,说我上线了Map map1 = Maps.newHashMap();map1.put("messageType",1);map1.put("username",username);sendMessageAll(JSON.toJSONString(map1),username);

//把自己的信息加入到map当中去clients.put(username, this);//给自己发一条消息:告诉自己现在都有谁在线Map map2 = Maps.newHashMap();map2.put("messageType",3);//移除掉自己Set set = clients.keySet();map2.put("onlineUsers",set);sendMessageTo(JSON.toJSONString(map2),username);}catch (IOException e){logger.info(username+"上线的时候通知所有人发生了错误");}

@OnErrorpublic void onError(Session session, Throwable error) {logger.info("服务端发生了错误"+error.getMessage());//error.printStackTrace();}/*** 连接关闭*/@OnClosepublic void onClose(){onlineNumber--;//webSockets.remove(this);clients.remove(username);try {//messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息Map map1 = Maps.newHashMap();map1.put("messageType",2);map1.put("onlineUsers",clients.keySet());map1.put("username",username);sendMessageAll(JSON.toJSONString(map1),username);}catch (IOException e){logger.info(username+"下线的时候通知所有人发生了错误");}logger.info("有连接关闭! 当前在线人数" + onlineNumber);}

/*** 收到客户端的消息** @param message 消息* @param session 会话*/@OnMessagepublic void onMessage(String message, Session session){try {logger.info("来自客户端消息:" + message+"客户端的id是:"+session.getId());JSONObject jsonObject = JSON.parseObject(message);String textMessage = jsonObject.getString("message");String fromusername = jsonObject.getString("username");String tousername = jsonObject.getString("to");//如果不是发给所有,那么就发给某一个人//messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息Map map1 = Maps.newHashMap();map1.put("messageType",4);map1.put("textMessage",textMessage);map1.put("fromusername",fromusername);if(tousername.equals("All")){map1.put("tousername","所有人");sendMessageAll(JSON.toJSONString(map1),fromusername);}else{map1.put("tousername",tousername);sendMessageTo(JSON.toJSONString(map1),tousername);}}catch (Exception e){logger.info("发生了错误了");}

public void sendMessageTo(String message, String ToUserName) throws IOException {for (WebSocket item : clients.values()) {if (item.username.equals(ToUserName) ) {item.session.getAsyncRemote().sendText(message);break;}}}

public void sendMessageAll(String message,String FromUserName) throws IOException {for (WebSocket item : clients.values()) {item.session.getAsyncRemote().sendText(message);}}

public static synchronized int getOnlineCount() {return onlineNumber;}

}

第四步:编写简易的前端页面

html>websockettitle>

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

/阅读下一篇/

返回网易首页 下载网易新闻客户端