• springboot+websocket 归纳收集



    websocket是h5后的技术,主要实现是一个长连接跟tomcat的comet技术差不多,但websocket是基于web协议的,有更广泛的支持。当然,在处理高并发的情况下,可以结合tomcat的asyncContext来实现长处理的异步返回等操作。

    1.引入依赖类

    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.18</version>
    </dependency>
    
    <!-- websocket dependency -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>

    这里主要是引入websocket的依赖类

    2.springboot配置websocket的入口bean

    在springboot的配置类下,引入以下的配置bean

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
    }

    3.实现websocket的后端处理逻辑

    package com.ouyang.server;
    
    import lombok.extern.slf4j.Slf4j;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    /**
    * Created by Administrator on 2018/3/25.
    */
    
    //@Slf4j
    @ServerEndpoint(value = "/websocket")
    @Component
    public class WebSocketServer {
    
    Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
    // 备用的同步hashmap
    //private static ConcurrentHashMap<Session,WebSocketServer> webSocketServerConcurrentHashMap = new ConcurrentHashMap();
    
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    
    /**
    * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
    this.session = session;
    webSocketSet.add(this); //加入set中
    addOnlineCount(); //在线数加1
    log.info("有新连接加入!当前在线人数为" + getOnlineCount());
    try {
    sendMessage("连接成功");
    } catch (IOException e) {
    log.error("websocket IO异常");
    }
    }
    // //连接打开时执行
    // @OnOpen
    // public void onOpen(@PathParam("user") String user, Session session) {
    // currentUser = user;
    // System.out.println("Connected ... " + session.getId());
    // }
    
    /**
    * 连接关闭调用的方法
    */
    @OnClose
    public void onClose() {
    webSocketSet.remove(this); //从set中删除
    subOnlineCount(); //在线数减1
    log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }
    
    /**
    * 收到客户端消息后调用的方法
    *
    * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
    log.info("来自客户端的消息:" + message);
    
    //群发消息
    for (WebSocketServer item : webSocketSet) {
    try {
    item.sendMessage("response message:"+message);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    //单发的信息
    sendMessage("currentWebsocket is ok!!! ");
    }
    
    /**
    *
    * @param session
    * @param error
    */
    @OnError
    public void onError(Session session, Throwable error) {
    log.error("发生错误");
    error.printStackTrace();
    }
    
    /**
    *
    * @param message
    * @throws IOException
    */
    public void sendMessage(String message) throws IOException {
    this.session.getBasicRemote().sendText(message);
    }
    
    
    /**
    * 群发自定义消息
    * */
    public static void sendInfo(String message) throws IOException {
    //log.info(message);
    for (WebSocketServer item : webSocketSet) {
    try {
    item.sendMessage(message);
    } catch (IOException e) {
    continue;
    }
    }
    }
    
    public static synchronized int getOnlineCount() {
    return onlineCount;
    }
    
    public static synchronized void addOnlineCount() {
    WebSocketServer.onlineCount++;
    }
    
    public static synchronized void subOnlineCount() {
    WebSocketServer.onlineCount--;
    }
    }

    至此,我们关于后台的websocket的主要实现类都实现了,接下来我们可以弄一个,测试的接口,用于给所有的websocket推送信息,如下:

    @RequestMapping(value="/publicSend",method= RequestMethod.GET)
    @ResponseBody
    public String pushVideoListToWeb2(String id) {
    try {
    WebSocketServer.sendInfo("有新客户呼入,sltAccountId:"+id);
    for(int i= 0;i<20;i++){
    WebSocketServer.sendInfo("有新客户呼入,testing:"+String.valueOf(i));
    }
    }catch (IOException e) {
    
    }
    return "success!";
    
    }

    4.前端测试页面的实现

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.springframework.org/schema/jdbc">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jquery.js"></script>
    <script src="/static/stomp.min.js"></script>
    <script src="/static/sockjs.min.js"></script>
    <script>
    //socket = new WebSocket("ws://localhost:8081/begenstom/websocket");
    var socket;
    if(typeof(WebSocket) == "undefined") {
    console.log("您的浏览器不支持WebSocket");
    }else {
    console.log("您的浏览器支持WebSocket");
    
    //实现化WebSocket对象,指定要连接的服务器地址与端口
    //socket = new WebSocket("ws://localhost:9094/starManager/websocket/张三");
    socket = new WebSocket("ws://localhost:8081/websocket");
    //打开事件
    socket.onopen = function () {
    console.log("Socket 已打开");
    for (var i=0;i<20;i++)
    {
    socket.send("这是来自客户端的消息1:" + i);
    }
    //socket.send("这是来自客户端的消息" + location.href + new Date());
    };
    //获得消息事件
    socket.onmessage = function (msg) {
    console.log(msg.data);
    //发现消息进入 调后台获取
    document.write(msg.data);
    };
    //关闭事件
    socket.onclose = function () {
    console.log("Socket已关闭");
    };
    //发生了错误事件
    socket.onerror = function () {
    alert("Socket发生了错误");
    }
    $(window).unload(function () {
    socket.close();
    });
    }
    </script>
    
    
    </head>
    <body>
    
    </body>
    </html>

    这里主要用到3个js,可以去github上去当一个。

    测试结果:==================


    参考地址:
    * https://blog.csdn.net/zhangdehua678/article/details/78913839
    * https://github.com/ayman-elgharabawy/Kafka-SpringBoot-WebSocket
    * 整合框架 https://github.com/527515025/springBoot

  • 相关阅读:
    Visual Studio 插件的开发
    EntityFramework 4.x 使用中遇到的问题 (2)
    F#学习笔记核心类型(二)
    F#学习笔记函数式编程(一)
    EntityFramework 4.x 使用中遇到的问题 (1)
    vue3项目一些小坑
    记一种拖拉拽编排流程的思路
    隐藏Jenkinsfile敏感信息
    Jenkins条件判断
    Jenkins 流水线语法自动部署
  • 原文地址:https://www.cnblogs.com/minsons/p/8644105.html
Copyright © 2020-2023  润新知