SpringBoot+WebSocket实现即时通讯的方法详解

SpringBoot+WebSocket实现即时通讯的方法详解

这篇文章主要为大家详细介绍了如何利用SpringBoot WebSocket实现即时通讯功能,文中示例代码讲解详细,对我们学习或工作有一定参考价值,需要的可以参考一下

目录

环境信息服务端实现导入依赖创建配置类创建一个注解式的端点并在其中通过配套注解声明回调方法服务端主动发送消息给客户端客户端实现Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)客户端实现在前端环境(vue)中使用websocket

环境信息

名称版本号春装

服务端实现

导入依赖

属国

groupIdorg.springframework.boot/groupId

artifact id spring-boot-starter-web socket/artifact id

/依赖关系

注意:Spring Boot在父工程中已经管理了websocket的版本信息,所以不用指定版本号也是可以的

创建配置类

包com。分支传美。配置;

导入org。spring框架。语境。注释。豆;

导入org。spring框架。语境。注释。配置;

导入组织。spring框架。网络。插座。服务器。标准。servendpointexporter

/**

* @作者484201132@qq.com戴逸

* @自2022/5/13 11:34

*/

@配置

公共类WebSocket配置{

@Bean

公共服务器端点导出器服务器端点导出器(){

返回新的servendpointexporter();

}

}

创建此配置类的目的只是为了把服务器端点导出器这个类的实例交给春天容器进行管理,您可以用任意一种方式交给容器,如使用@ Import(serverendpointexporter。类)这种方式等进行操作;此处只是我的编码风格如此;并非必须这样操作

创建一个注解式的端点并在其中通过配套注解声明回调方法

包com。分支传美。web套接字;

导入com。分支传美。web套接字。utils。会话管理器;

导入龙目岛。外部人员。SLF 4j。SLF 4j;

导入org。spring框架。刻板印象。组件;

导入javax。注释。资源;

导入javax。web套接字。*;

导入javax。web套接字。服务器。路径参数;

导入javax。web套接字。服务器。服务器端点;

/**

* @作者484201132@qq.com戴逸

* @自2022/3/7 15:47

*/

@Slf4j

@组件

@服务器端点(/arcticFoxServerEndpoint/{ websocketClientType } )

公共类ArcticFoxServerEndpoint {

私有静态会话管理器会话管理器

@资源

公共空集处理器(会话管理器会话管理器){

arcticfoxserverendpoint。会话管理器=会话管理器;

}

/**

* 建立连接成功的回调方法

*

* @param会话会话对象

* @param websocketClientType此参数就是路径中{websocketClientType}位置传入的参数

*/

@OnOpen

public void on open(Session Session,@ path param( websocketClientType )int websocketClientType){

sessionManager.onOpen(session,websocketClientType);

}

/**

* 当会话关闭时执行的回调方法

*

* @param会话会话对象

* @param websocketClientType此参数就是路径中{websocketClientType}位置传入的参数

*/

@OnClose

public void onClose(Session Session,@ path param( websocketClientType )int websocketClientType){

sessionManager.onClose(session,websocketClientType);

}

/**

* 当收到客户端信息时执行的回调方法

*

* @param会话会话对象

* @param消息客户端传递过来的信息

* @param websocketClientType此参数就是路径中{websocketClientType}位置传入的参数

*/

@OnMessage

public void on message(Session Session,String message,@ path param( websocketClientType )int websocketClientType){

会话管理器。on Message(session,Message,websocketClientType);

}

/**

* 当发生错误时的回调方法

*

* @param会话会话对象

* @param e异常对象

* @param websocketClientType此参数就是路径中{websocketClientType}位置传入的参数

*/

@OnError

public void on error(Session Session,Throwable e,@ path param( websocketClientType )int websocketClientType){

sessionManager.onError(session,e,websocketClientType);

}

}

@服务器端点注解标注此类为一个服务端的端点类,此注解有一个必须的参数,用于指定客户端访问的地址,本案例中为:/arcticFoxServerEndpoint,而路径后面的/{websocketClientType}这个是路径中参数的占位符,有点类似与Spring Mvc中休息接口和@路径变量注解的作用

注意事项:一定要将此类交给春天容器进行管理!还有一个坑就是,此类的实例时非单例的,所以如果要在此类中注入其他的豆子,不能使直接在属性上使用@资源注解或者@自动连线等注解进行注入,否则会报错。正确操作应该是把要注入的字段设置为静态的,然后通过非静态的设置方法进行注入,具体代码请看上方实例

服务端主动发送消息给客户端

通过上面的代码我们可以知道每个回调方法中都会收到一个会议对象,正如您所想,要向客户端发送消息正是要借助此对象;会议对象有一个getasynchremote方法,调用此方法可以得到一个远程端点。异步非同步(异步)对象,查看此对象,发现有很多派遣打头的方法;

是的,这些方法就是发送消息的方法,博主这个项目中主要是通过JSON来进行交互的,所以我使用了发送文本方法,示例代码:

远程端点async异步远程=会话。get async remote();

异步远程。发送文本(JSON字符串);

很显然中转变量异步远程没什么太大的用处,不如直接写成:

session.getAsyncRemote().发送文本(JSON字符串);

通过方法名看到,似乎还可以发送对象,二进制序列等,博主没有深入研究,有兴趣的小伙伴可以尝试尝试

客户端实现

一般来讲客户端应该是用Java 语言(一种计算机语言,尤用于创建网站)脚本实现,但是博主这个项目比较特殊,需要用Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)来实现客户端,下面博主先以Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)客户端说明其实现细节,然后再说再前端如何实现

Java客户端实现

导入依赖

属国

groupId组织。Java-web套接字/组Id

artifactId Java-web套接字/artifactId

版本1 .5 .3/版本

/依赖关系

其实Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)中实现WebSocket的第三方包还有很多,博主这个地方使用的是Java-WebSocket,有兴趣的小伙伴可以试试其他的包

建立连接和处理回调

包com。分支传美。web套接字;

导入com。更快的XML。杰克逊。核心。jsonprocessingexception

导入com。更快的XML。杰克逊。数据绑定。对象映射器;

导入com。分支传美。组件。付款部分;

导入com。分支传美。POJO。说明;

导入com。分支传美。utils。websocketclienttype

进口龙目岛。数据;

导入龙目岛。外部人员。SLF 4j。SLF 4j;

导入org。Java _ web套接字。客户。websocketclient

导入org。Java _ web套接字。伊努斯。就绪状态;

导入组织。Java _ web套接字。握手。服务器握手;

导入org。spring框架。靴子。语境。属性。配置属性;

导入org。spring框架。刻板印象。组件;

导入javax。注释。资源;

导入Java。网。uri

导入Java。网。urisynctaxexception

/**

* @作者484201132@qq.com戴逸

* @自2022/5/13 10:16

*/

@Slf4j

@组件

公共类ArcticFoxWebSocketClient {

@资源

私有对象映射程序对象映射器;

@资源

私人支付部分支付部分;

@资源

私有ArcticFoxWebSocketClientProperties属性;

public void established connection()引发了URISyntaxException {

WebSocketClient WebSocketClient=新WebSocketClient(新URI(字符串。格式( % s/% d ,属性。getwebsocketserverurl(),WebsocketClientType .支付_设备))){

@覆盖

公开无效(服务器握手服务器握手){

日志。info( WebSocketClient:on open:{ } ,服务器握手);

}

@覆盖

消息上的公共void(字符串JSON字符串){

尝试{

指令指令=对象映射器。读取值(JSON字符串,指令。类);

if (instructions.getType()==指令。通知_付款){

付款部分。queryunpaidordersandpay();

}否则{

抛出新的RuntimeException(错误的指令类型);

}

} catch(JsonProcessingException e){

e。printstacktrace();

}

}

@覆盖

public void onClose(int i,String s,boolean b) {

日志。info( WebSocketClient:onClose:I:{ },s:{},b:{} ,I,s,b);

尝试{

线程。睡眠(1000 * 20);

建立连接();

} catch(中断的异常| URISyntaxException e){

e。printstacktrace();

}

}

@覆盖

公共无效错误(异常e) {

日志。error( WebSocketClient:on error { } ,e . getmessage());

}

};

websocketclient。connect();

而(!(websocketclient。getreadystate()==就绪状态.打开){

尝试{

线程。睡眠(1000 * 2);

} catch (InterruptedException e) {

e。printstacktrace();

}

}

log.info(WebSocketClient:连接建立成功);

}

@数据

@组件

@配置属性(北极狐-we b-socket-client。属性’)

公共静态类ArcticFoxWebSocketClientProperties {

私有字符串webSocketServerUrl

}

}

代码解释:其实我的建立连接方法中上来就实例化了一个WebSocketClient类的实例,请注意,此类是个抽象类,我在这里用匿名实现类的方式实现的,此类有几个抽象方法需要实现,也就是onOpen,onMessage,onClose,onError四个方法,其作用其实已经是很见名知意了,和服务端的回调方法一样,就不过多解释;实例化此类需要传入一个上呼吸道感染对象,这个上呼吸道感染对象其实就是封装了对服务端连接的地址,由于博主不希望把服务端的地址给写死了,所以我配置到了配置文件中,然后通过字符串。格式静态方法配合占位符拼接全球资源定位器(统一资源定位器)地址和参数;路径的规则是:协议名://IP地址(或域名):端口号/服务端声明的地址/参数;举个例子:

ws://192。168 .88 .88:8080/arcticFoxServerEndpoint/1

ws://localhost:8080/arcticFoxServerEndpoint/2

ws://为协议;实例化WebSocketClient类的实例之后,调用其连接()方法即开始建立连接,调用getReadyState()方法可以获得其状态;由于我的服务端可能随时都连不上,所以我在客户端的onClose回调函数中进行了一个递归(20秒后),用于重新连接。

客户端向服务端发送消息

通过WebSocketClient类的实例,我们可以看到有以下方法,很明显派遣方法就是用来发送消息使用的

示例代码:

//判断一下是否为空

如果(对象。非空(webSocketClient)){

尝试{

//通过杰克逊将对象转换为json字符串(非必须)

字符串JSON字符串=对象映射器。writevalueasstring(反馈);

//发送信息

websocketclient。send(JSON字符串);

} catch(JsonProcessingException e){

e。printstacktrace();

}

}否则{

log.warn(未建立连接);

}

在前端环境(vue)中使用websocket

安装重新连接-网络插座包(非必须)

npm i -保存重新连接-网络插座

安装这个包是为了websocket能在断线之后重新连接,其实不使用这个包也是可以用原生Java 语言(一种计算机语言,尤用于创建网站)脚本实现的;但是他和原生的美国石油学会(美国石油协会)几乎一样;

示例代码:

从"重新连接-websocket "导入重新连接websocket

导出默认函数initializationWebsocket() {

let re connecting web socket=new re connecting web socket(` ws://localhost:8080/arcticFoxServerEndpoint/$ { 2 } `);

重新连接WebSocket.onopen=event={

console.log(on open:,event);

};

重新连接WebSocket.onmessage=event={

//事件对象中的数据//存储服务器发送的消息。

let parse=JSON . parse(event . data);

console . log( web socket on message:,parse);

};

重新连接WebSocket.onclose=event={

console.log(事件);

};

重新连接WebSocket.onerror=event={

console.log(事件);

};

//关闭窗口时断开连接

window . onbeforeunload=function(){

重新连接web socket . close();

}

}

在前端实现websocket相对简单,上面几行代码就行。不需要调用其他函数来连接。实例化之后,就开始连接了。

想服务端发送信息

前端发送信息比较简单,直接调用reconnectingWebSocket的send方法,传入要发送的数据即可。

以上就是本文对SpringBoot WebSocket中实现即时通讯的方法的详细讲解。有关SpringBoot WebSocket中即时消息的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

SpringBoot+WebSocket实现即时通讯的方法详解