1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

spring-boot-websocket总结回顾

前言

websocket的内容比我预期的要少,本来打算分三次分享,但是经过昨天和前天的分享,核心内容已经完结了,所以我们今天来做一个简单小结。

websocket总结回顾

相比于我们前两天刚分享的securitywebsocket确实比较少,不过它内容虽然不多,但是这项技术却很有用,比如你要搭建一个个人聊天系统或者做一个客服组件,那websocket就是最佳选择,而且兼容性方便也是没得说,根据我的实际测试IE11本身是支持websocket,如果老一点的IE,我们也可以通过STOMP来兼容。

今天我们的核心内容也是从一张脑图开始,公众号后台回复【spring-websocket】获取脑图源文件:

核心依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

核心配置

  • 创建一个服务节点池,本质上它就是一个节点容器
@Bean
public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
}

节点服务

@ServerEndpoint
  • 需要指定节点地址,客户端根据节点地址与服务端通信
@ServerEndpoint("/ws")
@Service
public class WebSocketService {
...
}

监听方法

  • @OnOpen:客户端建立连接时会调用该方法

    • 参数

      • Session
    @OnOpen
    public void onOpen(Session session) {
        String name = nameMap.get(session.getUserPrincipal().getName());
        this.session = session;
        webSocketServiceSet.add(this);
        addOnlineCount();
        logger.info("有新连接加入!当前在线人数为: {}", onlineCount.get());
        webSocketServiceSet.parallelStream().forEach(item -> {
            try {
                sendMessage(item.getSession(), String.format("%s加入群聊!", name));
            } catch (Exception e) {
                logger.error("发送消息异常:", e);
            }
        });
    }
    
  • @OnMessage:客户端发送消息时调用该方法

    • 参数

      • message
      • Session
    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("来自客户端的消息:{}", message);
        webSocketServiceSet.parallelStream().forEach(item -> {
            String name = nameMap.get(session.getUserPrincipal().getName());
            logger.info("{}发送了一条消息:{}", name, message);
            try {
                item.sendMessage(item.getSession(), String.format("%s:%s", name, message));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
    
  • @OnClose:客户端关闭websocket连接时回调该方法

    • 参数

      • Session
    @OnClose
    public void onClose(Session session) {
        logger.info("{}退出群聊!", session.getUserPrincipal().getName());
        webSocketServiceSet.remove(this);
        subOnlineCount();
    }
    
  • @OnError:客户端发生错误时调用该方法

    • 参数

      • Session
      • Throwable
    @OnError
    public void onError(Session session, Throwable t) {
        logger.error("发生错误:", t);
    }
    

前端

创建websocket对象
var websocket = new WebSocket("ws://localhost:8989/ws")
指定回调函数
  • open

    websocket.onopen = function () {
    // 方法实现
    }
    
  • error

    websocket.onerror = function () {
    // 方法实现
    }
    
  • message

    websocket.message = function () {
    // 方法实现
    }
    
  • close

    websocket.onclose = function () {
    // 方法实现
    }
    
发送消息
websocket.send(message)

STOMP兼容

对于不支持websocket的浏览器,我们需要通过stomp协议进行兼容,但是目前我接触到的浏览器包括IE都是支持websocket的。

配置类
  • 注解

    • @EnableWebSocketMessageBroker

      作用:启用websocketMessageBroker

  • 配置方法

    • registerStompEndpoints()

      • 注册节点

        registry.addEndpoint("/socket").withSockJS()
        
    • configureMessageBroker()

      • 指定客户端订阅路径前缀

        registry.enableSimpleBroker("/sub", "/queue")
        
      • 指定服务端点请求前缀

        registry.setApplicationDestinationPrefixes("/request")
        
接口
  • 发送广播消息

    @MessageMapping("/send")
    @SendTo("/sub/chat")
    public String sendMessage(String value) {
        logger.info("发送消息内容:{}", value);
        return value;
    }
    
  • 发送私有消息

    @MessageMapping("/sendToUser")
    public void sendToUser(Principal principal, String body) {
        String srcUser = principal.getName();
        String[] args = body.split(": ");
        String desUser = args[0];
        String message = String.format("【%s】给你发来消息:%s", webSocketService.getNameMap().get(srcUser), args[1]);
        // 发送到用户和监听地址
        simpMessagingTemplate.convertAndSendToUser(desUser, "/queue/customer", message);
    
    }
    
前端
  • 引入js包

    • stomp.js
    • sockjs.js
  • 建立STOMP连接

    • 创建SockJS实例

      var socket = new SockJS('/socket');
      
    • 创建stompClient

      var stompClient = Stomp.over(socket);
      
    • 建立连接

      stompClient.connect({}, function (frame) {
          // 建立连接后的回调
          setConnected(true);
      })
      
  • 断开stomp连接

    stompClient.disconnect()
    
  • 发送消息

    stompClient.send("/request/send", {}, message)
    
  • 接收方订阅消息

    stompClient.connect({}, function () {
        console.log("notice socket connected !");
        // 订阅消息地址
        stompClient.subscribe('/sub/chat', function (data) {
            $('#receive').html(data.body);
        });
    });
    

总结

websocket的内容相对比较简单,而且配置也不复杂,所以今天也没有太多要补充说明的,各位小伙伴如果对于之前的知识点还有疑问,可以再回顾下:

posted @ 2021-07-28 15:05  云中志  阅读(77)  评论(0编辑  收藏  举报