当前位置: 首页 > news >正文

使用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.导入依赖:

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-websocket</artifactId>  
</dependency> 

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

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

/*** WebSocket服务*/
@Component
@ServerEndpoint("/ws/{sid}")//根据路径匹配,以此请求服务端的组件
public class WebSocketServer {//存放会话对象private static Map<String, Session> sessionMap = new HashMap();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客户端:" + sid + "建立连接");sessionMap.put(sid, session);}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);}/*** 连接关闭调用的方法** @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);}/*** 群发** @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}
}

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

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/*** 开启WebSocket支持*/
@Configuration  
public class WebSocketConfig {  @Bean  public ServerEndpointExporter serverEndpointExporter() {  return new ServerEndpointExporter();  }  } 

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

import com.sky.Websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class WebSocketTask {@Autowiredprivate WebSocketServer webSocketServer;/*** 通过WebSocket每隔5秒向客户端发送消息*/@Scheduled(cron = "0/5 * * * * ?")public void sendMessageToClient() {webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));}
}

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

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

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

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>WebSocket Demo</title>
</head>
<body><input id="text" type="text" /><button onclick="send()">发送消息</button><button onclick="closeWebSocket()">关闭连接</button><div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;var clientId = Math.random().toString(36).substr(2);//判断当前浏览器是否支持WebSocketif('WebSocket' in window){//连接WebSocket节点websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);}else{alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function(){setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function(){setMessageInnerHTML("连接成功");}//接收到消息的回调方法websocket.onmessage = function(event){setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose = function(){setMessageInnerHTML("close");}//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function(){websocket.close();}//将消息显示在网页上function setMessageInnerHTML(innerHTML){document.getElementById('message').innerHTML += innerHTML + '<br/>';}//发送消息function send(){var message = document.getElementById('text').value;websocket.send(message);}//关闭连接function closeWebSocket() {websocket.close();}
</script>
</html>

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

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

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

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

		# WebSocketlocation /ws/ {proxy_pass   http://webservers/ws/;proxy_http_version 1.1;proxy_read_timeout 3600s;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "$connection_upgrade";}

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

	upstream webservers{server 127.0.0.1:8080 weight=90 ;#server 127.0.0.1:8088 weight=10 ;}

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

5.推送消息案例:

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

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

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

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

http://www.lryc.cn/news/408583.html

相关文章:

  • 【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十七章 Linux中断实验
  • 每日一题~961div2A+B+C(阅读题,思维,数学log)
  • Fireflyrk3288 ubuntu18.04添加Qt开发环境、安装mysql-server
  • 简化mybatis @Select IN条件的编写
  • Windows图形界面(GUI)-MFC-C/C++ - Control
  • SQL Server数据库安全:策略制定与实践指南
  • Spring Boot入门指南:留言板
  • Docker 中安装和配置带用户名和密码保护的 Elasticsearch
  • 面试官:说说JVM内存调优及内存结构
  • Ansible的脚本-----playbook剧本【下】
  • Mysql开启远程控制简化版,亲测有效
  • 【MQTT协议与IoT通信】MQTT协议的使用和管理
  • 根据题意写出完整的css,html和js代码【购物车模块页面及功能实现】
  • AWS免费层之后:了解和管理您的云服务成本
  • Linux定时同步系统时间到硬件时间
  • 网络编程——wireshark抓包、tcp粘包
  • el-table合计行更新问题
  • ChatGPT:数据库不符合第二范式示例
  • 27、美国国家冰雪中心(NSIDC)海冰密集度月数据下载与处理
  • vite环境下使用bootstrap
  • Laravel视图渲染封装
  • C++学习补充2:MySQL select 查询
  • uni-app声生命周期
  • 排序算法--堆排序
  • iPhone 在 App Store 中推出的 PC 模拟器 UTM SE
  • FastAPI删除mongodb重复数据(数据清洗)
  • 移动UI:排行榜单页面如何设计,从这五点入手,附示例。
  • 如何解决 uni-app 项目中 “文件查找失败:‘crypto-js‘“ 的问题
  • Apache DolphinScheduler 3.2.2 版本正式发布!
  • 汇川CodeSysPLC教程03-2-6 ModBus TCP