当前位置:   article > 正文

使用WebSocket协议调用群发方法将消息返回客户端页面

使用WebSocket协议调用群发方法将消息返回客户端页面

目录

一.C/S架构:

二.Http协议与WebSocket协议的区别:

1.Http协议与WebSocket协议的区别:

2.WebSocket协议的使用场景:

三.项目实际操作:

1.导入依赖:

2.通过WebSocket实现页面与服务端保持长连接:

3.在config创建WebSocketConfig配置类来开启WebSocket支持:

4.在nginx.conf中配置路径:

5.推送消息案例:


一.C/S架构:

我们都知道,JavaWeb项目通常是在服务器端部署的。一般我们在开发时候会用到 C / S 架构,也就是客户端 / 服务器。客户端是指用户的设备,比如个人电脑、手机或平板等,它们运行的是浏览器软件,通过HTTP协议向服务器发送请求并接收响应。服务器端则是专门用于处理这些请求的服务器,如Tomcat、Jetty或IIS这样的Web服务器,它们负责运行Java应用程序并执行业务逻辑。

当用户打开浏览器,输入URL访问JavaWeb应用时,浏览器会发起一个HTTP GET或POST请求到服务器的特定地址(即应用的URL)。服务器接收到这个请求后,解析其内容,调用相应的JavaServlet或JSP(Java Server Pages),执行预定义的业务逻辑,并生成HTML响应。然后,服务器将响应返回给客户端,客户端再呈现给用户。

二.Http协议与WebSocket协议的区别:

我们看下面的图:

学过 Javaweb 都会了解 Http 协议, Http 协议有一个缺陷:通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送信息。所以这个时候我们就需要一个协议来解决这个问题,而这时候就要介绍 WebSocket 协议。

1.Http协议与WebSocket协议的区别:

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。根据上图,图的右侧黄色框,其代表的是连接的生命周期,很容易发现 Http 的连接的声明周期断断续续,代表如果通过 Http 协议多次访问,就需要连接多次,这就叫做短链接,而 WebSocket 协议可以持久性的连接,也叫做长连接。还有就是 Http 协议的通信是单向的,基于请求响应模式,而  WebSocket 支持双向通信。

下面表格为上面的总结:

Http协议与WebSocket协议的区别
Http协议WebSocket协议
短连接长连接
单向通信双向通信

2.WebSocket协议的使用场景:

视频弹幕,网页聊天,体育实况更新......

三.项目实际操作:

1.导入依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-websocket</artifactId>
  4. </dependency>

2.通过WebSocket实现页面与服务端保持长连接:

在WebSocket包下导入 WebSocketServer( WebSocket 的服务端组件),用于与客户端通信:

  1. /**
  2. * WebSocket服务
  3. */
  4. @Component
  5. @ServerEndpoint("/ws/{sid}")//根据路径匹配,以此请求服务端的组件
  6. public class WebSocketServer {
  7. //存放会话对象
  8. private static Map<String, Session> sessionMap = new HashMap();
  9. /**
  10. * 连接建立成功调用的方法
  11. */
  12. @OnOpen
  13. public void onOpen(Session session, @PathParam("sid") String sid) {
  14. System.out.println("客户端:" + sid + "建立连接");
  15. sessionMap.put(sid, session);
  16. }
  17. /**
  18. * 收到客户端消息后调用的方法
  19. *
  20. * @param message 客户端发送过来的消息
  21. */
  22. @OnMessage
  23. public void onMessage(String message, @PathParam("sid") String sid) {
  24. System.out.println("收到来自客户端:" + sid + "的信息:" + message);
  25. }
  26. /**
  27. * 连接关闭调用的方法
  28. *
  29. * @param sid
  30. */
  31. @OnClose
  32. public void onClose(@PathParam("sid") String sid) {
  33. System.out.println("连接断开:" + sid);
  34. sessionMap.remove(sid);
  35. }
  36. /**
  37. * 群发
  38. *
  39. * @param message
  40. */
  41. public void sendToAllClient(String message) {
  42. Collection<Session> sessions = sessionMap.values();
  43. for (Session session : sessions) {
  44. try {
  45. //服务器向客户端发送消息
  46. session.getBasicRemote().sendText(message);
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. }
  52. }

3.在config创建WebSocketConfig配置类来开启WebSocket支持:

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  4. /**
  5. * 开启WebSocket支持
  6. */
  7. @Configuration
  8. public class WebSocketConfig {
  9. @Bean
  10. public ServerEndpointExporter serverEndpointExporter() {
  11. return new ServerEndpointExporter();
  12. }
  13. }

为了方便查看我们使用效果,我们创建一个定时任务类(用了SpringTask框架):

  1. import com.sky.Websocket.WebSocketServer;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.scheduling.annotation.Scheduled;
  4. import org.springframework.stereotype.Component;
  5. import java.time.LocalDateTime;
  6. import java.time.format.DateTimeFormatter;
  7. @Component
  8. public class WebSocketTask {
  9. @Autowired
  10. private WebSocketServer webSocketServer;
  11. /**
  12. * 通过WebSocket每隔5秒向客户端发送消息
  13. */
  14. @Scheduled(cron = "0/5 * * * * ?")
  15. public void sendMessageToClient() {
  16. webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));
  17. }
  18. }

随后,我们启动这个项目,在前段页面会每隔五秒输出内容。

 上面是我们服务端给客户端发消息,同样我们基于 WebSocket 协议也可以通过客户端给服务端发消息。

当然我们下面看一下前端的代码展示:

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>WebSocket Demo</title>
  6. </head>
  7. <body>
  8. <input id="text" type="text" />
  9. <button onclick="send()">发送消息</button>
  10. <button onclick="closeWebSocket()">关闭连接</button>
  11. <div id="message">
  12. </div>
  13. </body>
  14. <script type="text/javascript">
  15. var websocket = null;
  16. var clientId = Math.random().toString(36).substr(2);
  17. //判断当前浏览器是否支持WebSocket
  18. if('WebSocket' in window){
  19. //连接WebSocket节点
  20. websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);
  21. }
  22. else{
  23. alert('Not support websocket')
  24. }
  25. //连接发生错误的回调方法
  26. websocket.onerror = function(){
  27. setMessageInnerHTML("error");
  28. };
  29. //连接成功建立的回调方法
  30. websocket.onopen = function(){
  31. setMessageInnerHTML("连接成功");
  32. }
  33. //接收到消息的回调方法
  34. websocket.onmessage = function(event){
  35. setMessageInnerHTML(event.data);
  36. }
  37. //连接关闭的回调方法
  38. websocket.onclose = function(){
  39. setMessageInnerHTML("close");
  40. }
  41. //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  42. window.onbeforeunload = function(){
  43. websocket.close();
  44. }
  45. //将消息显示在网页上
  46. function setMessageInnerHTML(innerHTML){
  47. document.getElementById('message').innerHTML += innerHTML + '<br/>';
  48. }
  49. //发送消息
  50. function send(){
  51. var message = document.getElementById('text').value;
  52. websocket.send(message);
  53. }
  54. //关闭连接
  55. function closeWebSocket() {
  56. websocket.close();
  57. }
  58. </script>
  59. </html>

这组前端与后端的代码一起使用,就是我们 WebSocket 协议的使用方式。

而我们在使用 WebSocket 协议的时候,实际上跟 Http 协议一样,都会需要经过 nginx 转发,然后才可以转发到我们的后端,所以我们在使用WebSocket协议还需要我们提前再 nginx.conf 配置好这个路径。

4.在nginx.conf中配置路径:

我们在 server{} 内加入下面代码:

  1. # WebSocket
  2. location /ws/ {
  3. proxy_pass http://webservers/ws/;
  4. proxy_http_version 1.1;
  5. proxy_read_timeout 3600s;
  6. proxy_set_header Upgrade $http_upgrade;
  7. proxy_set_header Connection "$connection_upgrade";
  8. }

通过上面的代码就可以将我们的请求转发到webservers,而webservers在我们上面同样声明其路径是本地路径ip与端口号。

  1. upstream webservers{
  2. server 127.0.0.1:8080 weight=90 ;
  3. #server 127.0.0.1:8088 weight=10 ;
  4. }

 当然这个最上级的目录肯定是http{}内写的,所以这个请求就是基于nginx的反向代理,然后将请求转发过来。随后我们基于调用群发方法就可以把消息推送到客户端页面。

5.推送消息案例:

推送消息的格式可用当今主流的json格式,随后我们看一下代码案例:

我们想将信息推送过去,可以将信息封装map集合,然后调用JSON.toJSONString()方法就可以将map集合转成json串,并调用群发方法发送至客户端。

  1. //通过WebSocket向客户端浏览器推送消息type orderId content
  2. Map map = new HashMap();
  3. map.put("type",1);
  4. map.put("orderId",ordersDB.getId());
  5. map.put("content","订单号:" + outTradeNo);
  6. String json = JSON.toJSONString(map);
  7. //推送
  8. webSocketServer.sendToAllClient(json);

好了,今天的内容就到这里,Javaweb内容持续编辑中,感谢收看!!!

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/910425
推荐阅读
相关标签
  

闽ICP备14008679号