springboot整合websocket使用介绍

文章目录

  • 系列文章目录
    • Springboot集成Netty
    • Springboot集成Rabbitmq
    • Springboot集成Retry
    • springboot集成websocket
    • Springboot集成Redis
    • springboot整合rabbitmq使用示例
  • 前言
  • 一、WebSocket是什么?
  • 二、使用步骤
    • 引入库
    • 录入配置
      • 服务端
        • 注册netty服务端配置
        • 注册ws请求处理器
      • 客户端
        • Java 客户端
          • 注册客户端
          • 注册客户端配置
        • Vue客户端
          • 引入vue以及axios
          • 相应处理逻辑
  • 三、 使用步骤
    • 启动类上加上websocket启动注解
    • 配置websocket服务器端url地址
    • 服务端监听消息处理器
    • 客户端发送ws协议数据控制器
  • 四、最终效果
    • 前端页面
    • 服务器端日志
    • 借助idea插件市场中的Http Client插件进行模拟请求
  • 五、总结
  • 六、项目示例源码


系列文章目录

Springboot集成Netty

Springboot集成Rabbitmq

Springboot集成Retry

springboot集成websocket

Springboot集成Redis

springboot整合rabbitmq使用示例

前言

本文介绍了整合spring-websocket的步骤,通过基于Vue搭建的客户端通过websocket协议访问服务器端。


提示:以下是本篇文章正文内容,下面案例可供参考

一、WebSocket是什么?

是一种基于tcp的web通讯协议、是全双工通讯的,换言之客户端以及服务端可以相互发起通讯

二、使用步骤

引入库

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-websocketartifactId>
dependency>

录入配置

服务端

注册netty服务端配置
@Configuration
@ConfigurationProperties(prefix = "websocket")
@Data
@EnableConfigurationProperties
public class WebSocketProperties {
    /**
     * 服务器url
     */
    private String url;
}


注册ws请求处理器
@Configuration
@Import(WebSocketProperties.class)
public class WebSocketConfig{
    /**
     * 注册一个扫描ServerEndpoint注解处理器
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

客户端

Java 客户端
注册客户端
@ClientEndpoint
@Slf4j
public class WebSocketClient {
    @OnOpen
    public void open(Session s) {
        log.info("客户端开启了");
    }
    @OnClose
    public void close(CloseReason c) {
        log.info("客户端关闭了"+ c.getReasonPhrase());

    }
    @OnError
    public void error(Throwable t) {
        log.info("客户端发生错误");
    }
    @OnMessage
    public void message(String message, Session session) {
        log.info("客户端获取到服务端的信息:"+ message);
    }
}

注册客户端配置
@Configuration
public class WebSocketClientConfig {
    @Autowired
    WebSocketProperties webSocketProperties;

    /**
     * 连接服务器端
     * @param userName
     * @return
     * @throws Exception
     */
    public Session connect(String userName) throws Exception {
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        //设置消息大小最大为10M
        container.setDefaultMaxBinaryMessageBufferSize(10 * 1024 * 1024);
        container.setDefaultMaxTextMessageBufferSize(10 * 1024 * 1024);
        String uri = "ws://" + webSocketProperties.getUrl() + "/" + userName;
        return container.connectToServer(WebSocketClient.class, URI.create(uri));
    }

    /**
     * 发送信息
     * @param msg
     * @param userName
     * @throws Exception
     */
    public void sendMsg(String msg, String userName) throws Exception {
        Session session = connect(userName);
        session.getBasicRemote().sendText(msg);
    }
}
Vue客户端
引入vue以及axios
<script src="../js/vue.js">script>
<script src="../js/axios.js">script>
相应处理逻辑
<div id="root">
    <h1>hello {{userName}}h1>
    <input type="text" v-model="sendMsg" placeholder="请输入需要发送的信息">
    <button @click="wsSendMessage">发送webSocket信息button>
    <div>客户端接收到的消息:div>
    <ul>
        <li v-for="(data,index) in serverMsg" :key="index">{{data}}li>
    ul>
div>
<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data() {
            return {
                sendMsg: '',
                ws: null,
                wsUrl: 'ws://localhost:8080/websocket',
                url: 'http://localhost:8080/websocket/getUserName',
                userName: '',
                serverMsg: []
            }
        },
        created() {
            this.getUserName()
        },
        methods: {
            getUserName() {
                axios.get(this.url).then(
                    response => {
                        this.initWebSocket(response.data.msg)
                    },
                    error => {
                        console.log(error)
                    }
                )
            },
            // 初始化websocket
            initWebSocket(userName) {
                if ('WebSocket' in window) {
                    this.userName = userName
                    this.ws = new WebSocket(this.wsUrl + '/' + userName)
                    this.ws.onopen = this.wsOnOpen
                    this.ws.onerror = this.wsOnError
                    this.ws.onmessage = this.wsOnMessage
                    this.ws.onclose = this.wsOnClose
                } else {
                    console.log('您的浏览器不支持WebSocket')
                }
            },
            // 打开连接
            wsOnOpen() {
                console.log('和服务器连上了')
            },
            // 接收信息
            wsOnMessage(data) {
                console.log('客户端接收到消息了', data.data)
                this.serverMsg.unshift(data.data)
            },
            // 关闭连接
            wsOnClose() {
                console.log('和服务器断开连接了');
            },
            // 监听错误事件
            wsOnError(error) {
                console.log('websocket通讯过程发生异常', error);
            },
            // 发送消息给服务器端
            wsSendMessage() {
                this.ws.send(JSON.stringify(this.sendMsg))
            }

        }

    })
script>
body>

三、 使用步骤

启动类上加上websocket启动注解

@SpringBootApplication
@Slf4j
@EnableWebSocket
public class SpringBootExampleApplication {
    public static void main(String[] args){
        SpringApplication.run(SpringBootExampleApplication.class, args);
    }
}

配置websocket服务器端url地址

# websocket 配置
websocket:
  url: localhost:8080/websocket

服务端监听消息处理器

@ServerEndpoint("/websocket/{username}")
@Component
@Slf4j
public class WebSocketController {
    public static Map<String,Session> sessionMap = new HashMap<>();
    /**
     * 连接建立的时候
     * @param session
     * @param userName
     * @throws IOException
     */
    @OnOpen
    public void openConnetion(Session session, @PathParam("username")String userName) throws IOException {
        sessionMap.put(userName,session);
        log.info("检测到客户端{}上线了",userName);
        session.getBasicRemote().sendText(userName + "上线了");
    }

    /**
     * 接收消息的时候
     * @param session
     */
    @OnMessage
    public void message(Session session,String message,@PathParam("username") String userName){
        log.info("检测到客户端{}发来消息了:{}",userName,message);
        // 发送给其他的session信息
        sessionMap.forEach((k,v)->{
            if(!k.equals(userName)){
                try {
                    v.getBasicRemote().sendText("【"+ userName + "】:" + message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 客户端关闭
     * @param session
     */
    @OnClose
    public void close(Session session,@PathParam("username") String userName){
        log.info("客户{}下线了",userName);
        sessionMap.remove(userName);
    }

    @OnError
    public void error(Session session,Throwable throwable){
        log.info("检测到session{}出现错误了",session.getId());
        log.error(ExceptionUtil.printStackTrace((Exception) throwable));
    }


}

客户端发送ws协议数据控制器

@RestController
@RequestMapping("websocket")
@CrossOrigin
public class WebSocketClientController {
    /**
     * 发送信息
     */
    @Autowired
    WebSocketClientConfig myWebSocketClientConfig;
    @GetMapping("sendMsg")
    public AjaxResult sendMsg(String msg,String userName) throws Exception {
        myWebSocketClientConfig.sendMsg(msg, userName);
        return AjaxResult.success();
    }

    /**
     * 模拟获取用户名
     * @return
     */
    @GetMapping("getUserName")
    public AjaxResult getUserName(){
        return AjaxResult.success(RandomUtil.randomString(5));
    }
}

四、最终效果

前端页面

开两个前端页面模仿两个客户端

springboot整合websocket使用介绍_第1张图片
springboot整合websocket使用介绍_第2张图片

服务器端日志

[INFO ] 2022-05-17 13:59:41 [http-nio-8080-exec-1:103872:c.g.e.c.WebSocketController:39] - 检测到客户端opfaf上线了
[INFO ] 2022-05-17 14:00:13 [http-nio-8080-exec-5:136579:c.g.e.c.WebSocketController:39] - 检测到客户端o5a6g上线了
[INFO ] 2022-05-17 14:00:42 [http-nio-8080-exec-4:164929:c.g.e.c.WebSocketController:49] - 检测到客户端o5a6g发来消息了:"nice to meet you"
[INFO ] 2022-05-17 14:00:55 [http-nio-8080-exec-6:177835:c.g.e.c.WebSocketController:49] - 检测到客户端opfaf发来消息了:"nice to meet you too"

借助idea插件市场中的Http Client插件进行模拟请求

springboot整合websocket使用介绍_第3张图片

日志打印

[INFO ] 2022-05-17 14:09:14 [http-nio-8080-exec-7:676990:c.g.e.c.WebSocketController:39] - 检测到客户端123上线了
[INFO ] 2022-05-17 14:09:14 [http-nio-8080-exec-9:676997:c.g.w.c.WebSocketClient:22] - 客户端开启了
[INFO ] 2022-05-17 14:09:14 [WebSocketClient-AsyncIO-16:677000:c.g.w.c.WebSocketClient:35] - 客户端获取到服务端的信息:123上线了
[INFO ] 2022-05-17 14:09:14 [http-nio-8080-exec-10:677001:c.g.e.c.WebSocketController:49] - 检测到客户端123发来消息了:你好
[INFO ] 2022-05-17 14:09:19 [http-nio-8080-exec-3:681981:c.g.e.c.WebSocketController:39] - 检测到客户端234上线了
[INFO ] 2022-05-17 14:09:19 [http-nio-8080-exec-1:681984:c.g.w.c.WebSocketClient:22] - 客户端开启了
[INFO ] 2022-05-17 14:09:19 [WebSocketClient-AsyncIO-16:681987:c.g.w.c.WebSocketClient:35] - 客户端获取到服务端的信息:234上线了
[INFO ] 2022-05-17 14:09:19 [http-nio-8080-exec-5:681987:c.g.e.c.WebSocketController:49] - 检测到客户端234发来消息了:你好啊
[INFO ] 2022-05-17 14:09:19 [WebSocketClient-AsyncIO-16:681988:c.g.w.c.WebSocketClient:35] - 客户端获取到服务端的信息:【234】:你好啊

五、总结

上述介绍了如何整合spring-websocket以及提供客户端服务端相互通讯基于Vue实现的案例,模块暂时不够完善,后续结合项目开发注意事项整合在一块。

六、项目示例源码

模块源码:https://gitee.com/teajoy/springboot-modules/tree/master/springboot-websocket
使用模块示例源码: https://gitee.com/teajoy/springboot-modules/tree/master/springboot-example

你可能感兴趣的:(websocket,springboot,websocket,spring,boot,java)