网站搭建在线支付,网站建设公司有多少钱,搜索引擎优化seo专员,wordpress 数据库表一、WebSocket是什么#xff1f;
WebSocket是在单个TCP连接上进行全双工通信的协议#xff0c;可以在服务器和客户端之间建立双向通信通道。
WebSocket 首先与服务器建立常规 HTTP 连接#xff0c;然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。
WebSocket使得…一、WebSocket是什么
WebSocket是在单个TCP连接上进行全双工通信的协议可以在服务器和客户端之间建立双向通信通道。
WebSocket 首先与服务器建立常规 HTTP 连接然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。
WebSocket使得客户端和服务器之间的数据交换变得更加简单允许服务端主动向客户端推送数据。在WebSocket API中浏览器和服务器只需要完成一次握手两者之间就直接可以创建持久性的连接并进行双向数据传输。
二、WebSocket的优点
1.较少的控制开销。在连接创建后服务器和客户端之间交换数据时用于控制协议的数据包头部较小。在不包含扩展的情况下对于服务器到客户端的内容此头部大小只有2至10字节和数据包长度有关对于客户端到服务器的内容此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部此项开销显著减少了。
2.更强的实时性。由于协议是全双工的所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应延迟明显更少即使是和Comet等类似的长轮询比较其也能在短时间内更多次地传递数据。
3.保持连接状态。与HTTP不同的是WebSocket需要先创建连接这就使得其成为一种有状态的协议之后通信时可以省略部分状态信息而HTTP请求可能需要在每个请求都携带状态信息比如身份认证等。
4.更好的二进制支持。Websocket定义了二进制帧相对HTTP可以更轻松地处理二进制内容。
5.可以支持扩展。Websocket定义了扩展用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
6.更好的压缩效果。相对于HTTP压缩Websocket在适当的扩展支持下可以沿用之前内容的上下文在传递类似的数据时可以显著地提高压缩率。
三、项目实战
1.引入依赖
!--websocket--
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-websocket/artifactId
/dependency
完整的pom文件如下所示:
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.14/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.example/groupIdartifactIdWebSocketChatDemo/artifactIdversion0.0.1-SNAPSHOT/versionnameWebSocketChatDemo/namedescriptionWebSocketChatDemo/descriptionpropertiesjava.version1.8/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--websocket--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-websocket/artifactId/dependency!--lombok插件依赖--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project2.创建SystemWebSocketHandler类
package com.example.websocketchatdemo.websocket;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** author qx* date 2023/8/22* des WebSocket处理类*/
Slf4j
Component
public class SystemWebSocketHandler implements WebSocketHandler {// 存储所有客户端会话private static final ListWebSocketSession sessionList new ArrayList();/*** 与服务器连接成功*/Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {log.info(客户端成功建立连接:{}, session.getId());sessionList.add(session);}/*** 接受客户端的消息*/Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage? message) throws Exception {// 获取客户端的消息String msg message.getPayload().toString();log.info(接收到客户端的消息:{}, msg);sendMsg(msg);}/*** 给所有客户端发送消息** param msg 消息内容* throws IOException*/private void sendMsg(String msg) throws IOException {for (WebSocketSession session : sessionList) {if (session.isOpen()) {session.sendMessage(new TextMessage(msg));}}}/*** 通讯异常*/Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {log.error(通讯出现异常);}/*** 连接关闭*/Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {log.info(连接关闭);}/*** 是否允许分段发送*/Overridepublic boolean supportsPartialMessages() {// 一次性发送消息return false;}
}3.创建WebSocket配置类
这个配置类主要进行跨域的配置。
package com.example.websocketchatdemo.websocket;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;/*** author qx* date 2023/8/22* des WebSocket配置类*/
Configuration
EnableWebSocket
public class WebSocketConfig implements WebMvcConfigurer, WebSocketConfigurer {Autowiredprivate SystemWebSocketHandler handler;Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {// 设置WebSocket服务器地址 ws://localhost:8080/SpringBootWebSocketregistry.addHandler(handler, /SpringBootWebSocket).setAllowedOrigins(*);}
}4.前台页面编写
!DOCTYPE html
html langen
headmeta charsetUTF-8title聊天室/title/head
body
聊天消息内容:
br/
textarea idchat_content readonly styleheight: 400px;width: 600px/textarea
br/输入框:
br/
divtextarea idin_content placeholder请输入内容 styleheight: 100px;width: 500px/textarea
/div
button typebutton idbtn_send发送消息/button
br/br/
label用户:/label
divinput typetext idin_name placeholder请输入姓名/
/div
br/
button typebutton idbtn_join进入聊天室/button
button typebutton idbtn_quit离开聊天室/button
script srchttp://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js/script
script$(function () {var socketUrl ws://localhost:8080/SpringBootWebSocket;var ws null;$(#btn_join).click(function () {if (ws ! null) {alert(用户[ $(#in_name).val() ]已加入连接);return;}// 判断当前浏览器是否支持WebSocketif (WebSocket in window) {ws new WebSocket(socketUrl)} else {alert(当前浏览器不支持WebSocket);}// 建立连接ws.onopen function (event) {console.log(与服务器建立连接);ws.send(您的好友[ $(#in_name).val() ]上线了);}// 接收服务端返回给前端的消息ws.onmessage function (event) {$(#chat_content).append(event.data \n);}// 连接关闭ws.onclose function () {console.log(与服务器断开连接)$(#chat_content).append(用户[ $(#in_name).val() ]离开聊天室 \n);$(#in_name).val();}});//发送消息$(#btn_send).click(function () {if (ws null) {alert(该用户不在线);return;}var msg $(#in_content).val();ws.send(用户[ $(#in_name).val() ] msg);})// 离开聊天室$(#btn_quit).click(function () {ws.send(用户[ $(#in_name).val() ]离开聊天室!);$(#in_content).val();ws.close();})})
/script
/body
/html5.控制器编写
主要编写一个跳转到聊天室的请求
package com.example.websocketchatdemo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;/*** author qx* date 2023/8/22* des 测试*/
Controller
RequestMapping(/chat)
public class IndexController {/*** 跳转到聊天室*/GetMapping(/index)public String toChat() {return index;}
}6.测试
我们启动项目打开两个聊天页面。 方便设置两个用户加入聊天室 然后在一个用户中发送消息我们可以看到两个聊天窗口的消息同步了。 当一个用户退出聊天室时会提示用户退出聊天室。 这个时候另一个用户发送消息只能自己看到了。 如果想测试多个用户再从新打开一个页面进入聊天室就可以了。