(1)websocket
websocket(简写为ws),是一种轻量化的协议,经过最开始的握手阶段以后,前后端之间允许自由地发送信息不受限制(建议发送json字符串).虽然理论上这个东西是属于协议内容,但是已经被疯狂封装得像框架一样了.
websocket协议具有天然的优势处理前端多线程并发,并且只需要一个后端就能完成服务.在各大视频网站上经常能见到使用ws技术构建的简单聊天室项目.难能可贵的是,java,javascript都引入了相关的内容.
本文主要介绍使用,对标面向对象的实验,需要详细看待原理建议去看文档内容
另外,websocket最重要的是四种状态和他们的监听函数,open,close,message,error
分别代表:某个用户开启服务,某个用户关闭服务,某一端接收信息,某一端发生错误
(2)前端部署和发送信息
1.在前端部署websocket内容
websocket ws = new WebSocket("ws://127.0.0.1:8080/imserver/" + MyUsername);
很简单,直接创建websocket即可连接到后端(后端这个网址怎么来的我们后续再讨论,这个myUsername是我自己加上的内容,相当于传入一个参数,可以先不用管)
2.前端发送信息
let oj={
signal:8,
to:self.counterpart
}
self.ws.send(JSON.stringify(oj));
我这里举了个例子,建立了一个对象,然后转化为json字符串,直接找到对应的ws对象,然后使用send即可
3.前端接收信息
前端接收信息和厚度按一样,建立事件监听器,然后创建回调函数
this.ws.onopen = function () {
}
this.ws.onclose=function(){
}
this.ws.onmessage = function (event) {
//event是个接收到的1信息
}
(3)后端部署websocket
后端部署websocket有点麻烦....这里主要讲解springboot框架下的部署
首先在pom文件中部署如下几个依赖
<!--websocket启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热部署内容(不知道是干啥的)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
然后创建如下几个文件
webConfig,这个是打开后端的拦截器,防止出现不能访问的情况
package com.example.demochat.common.Config;
import com.example.demochat.component.AuthInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/imserver/**");
}
}
websocketConfig,ws有关的部署
package com.example.demochat.common.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
链接的时候用到的一个继承类
package com.example.demochat.component;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在此处实现身份验证逻辑
return true; // true 表示继续执行后续的拦截器或处理器方法,false 则会中断请求处理
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要是用于资源清理工作)
}
}
最后是核心文件,
这个东西里面就是我们websocket的基本逻辑
首先是建立一个链接,要借用注解来声明这里是都服务器的终端
里面会用到那些监听方法,有一个好消息是,我们不需要继承websocket这个类或者说这个接口,然后重写里面的方法.现在可以通过注释来给几个监听函数添加具体的回调
//建立一个双通道的webSocket类
@ServerEndpoint("/imserver/{username}")
//这是一个声明,声明这里是服务器的终端,可以通过这个路径访问
//{}代表占位符,可以通过@PathParam注解获取这个参数
@Component
public class WebSocketServer {
//下面是四个基础方法,当触发对应事件的时候,注解就会调用这些方法
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) throws IOException {
}
//移除某个用户
@OnClose
public void onClose(Session session, @PathParam("username") String username) throws IOException {
}
@OnMessage
public void onMessage(String message,Session session,@PathParam("username") String username) throws IOException {
}
@OnError
public void onError(Session session , Throwable err){//这里的参数类型必须是可抛出"Throwable"
}
}
对应的注解,标志着这个函数会在什么事件发生的时候调用
另外注意其中的参数,Session对象代表的是当前触发事件的具体对象,也就是前端窗口/用户,当用户触发对应事件的时候,就会填入对应参数中message参数代表的是传递进来的信息
Throwable是需要抛出的从错误
这些参数是必须的
2.后端发送请求:文章来源:https://uudwc.com/A/GdPRz
session.getBasicRemote().sendText(message);
直接让对应的窗口对象接收即可
利用session对象的对应方法发送消息即可文章来源地址https://uudwc.com/A/GdPRz