webSocket简单入门使用

需求:在新增报警事件和处理告警事件同时将消息进行推送

webSocket有什么用?

系统中的实时消息通讯是很常见的。之前的解释方式是使用轮询技术(具体我不懂,没使用过),但轮询技术的缺点就是需要反复发送请求。webSocket的出现机制就是可以不需要反复发送请求,又能做到实时通信。

webSocket怎么用?

知道了webSocket的作用,那它是怎么在代码中实现的。代码例子如下:

代码说明:必要注解

@ServerEndpoint:该注释表示将WebSocket服务器运行在ws://[Server端IIP]:[Server端端口]/websocket/echo

​ 注意:使用该注解的类必须要有一个无参构造方法

@OnOpen :连接时调用

@OnClose:断开时调用

@OnError:错误时调用

@OnMessage:客户端发送消息时调用

自定义方法:

sendAll(String message):消息群发送

sendInfo(String userId, String message ):消息指定发送

@ServerEndpoint("/websocket/{userId}")
@Component
public class MyWebsocketServer {

    public MyWebsocketServer() {
        log.info("启动");
    }

    /**
     * The Log.
     */
    static Log log=LogFactory.get(MyWebsocketServer.class);
    
    /**
     * 存放所有在线的客户端
     */
    private static Map<String, Session> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        log.info("有新的客户端连接了: {}", userId);
        //将新用户存入在线的组
        clients.put(userId, session);
        log.info("当前在线人数: {}", clients.size());
    }

    /**
     * 客户端关闭
     * @param session session
     */
    @OnClose
    public void onClose(Session session, @PathParam(value = "userId") String userId) {
        log.info("有用户断开了, id为:{}", userId);
        //将掉线的用户移除在线的组里
        clients.remove(userId);
        log.info("当前在线人数: {}", clients.size());
    }

    /**
     * 发生错误
     * @param throwable e
     */
    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }

    /**
     * 收到客户端发来消息
     * @param message  消息对象
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("服务端收到客户端发来的消息: {}", message);
        sendAll(message);
    }

    /**
     * 群发消息
     * @param message 消息内容
     */
    public static void sendAll(String message) {
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
            sessionEntry.getValue().getAsyncRemote().sendText(message);
            log.info("发送消息: {}", message);
        }
    }

    /**
     * 发消息
     * @param message 消息内容
     */
    public static void sendInfo(String userId, String message ) {
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
            if(sessionEntry.getKey().equals(userId)){
                sessionEntry.getValue().getAsyncRemote().sendText(message);
                log.info("发送消息: {}", message);
            }
        }
    }

业务代码调用

 public Result processingAlarmEventPush(String ids) {
        pushAlarm();
        return ResultUtil.success();
    }
   private void pushAlarm(){
        //重新查询所有告警并推送
        Map<String, List<AlarmVO>> allAlarm = getAllAlarm();
        if(allAlarm == null){
            MyWebsocketServer.sendAll("");
        }else {
            MyWebsocketServer.sendAll(allAlarm.keySet().toString());
        }
    }

webSocket怎么测试?

测试网址:【http://www.websocket-test.com/】

填入之前设置好的地址:ws://localhost:8075/camp/websocket/aa

点击连接时候会触发OnOpen函数,控制台输出:

2020-08-07 15:01:55.020  INFO 10208 --- [nio-8075-exec-1] c.s.s.c.websocket.MyWebsocketServer      : 启动
2020-08-07 15:01:55.024  INFO 10208 --- [nio-8075-exec-1] c.s.s.c.websocket.MyWebsocketServer      : 有新的客户端连接了: aa
2020-08-07 15:01:55.024  INFO 10208 --- [nio-8075-exec-1] c.s.s.c.websocket.MyWebsocketServer      : 当前在线人数: 1

点击断开时会触发OnClose函数,控制台输出:

2020-08-07 15:03:16.339  INFO 10208 --- [nio-8075-exec-2] c.s.s.c.websocket.MyWebsocketServer      : 有用户断开了, id为:aa
2020-08-07 15:03:16.340  INFO 10208 --- [nio-8075-exec-2] c.s.s.c.websocket.MyWebsocketServer      : 当前在线人数: 0

业务逻辑发送数据,控制台输出:

2020-08-07 15:05:02.163  INFO 10208 --- [nio-8075-exec-5] c.s.smartweb.security.filter.SsoFilter   : .............. /camp/alarm/insertPush
2020-08-07 15:05:02.168  INFO 10208 --- [nio-8075-exec-5] c.s.s.c.websocket.MyWebsocketServer      : 发送消息: [testname3, testname2, testname1]

测试网页输出:

这里很关键,网页有输出就意味着服务端已经主动向客户端发送信息,这就和轮询方式的最大区别

服务器 15:5:2
[testname3, testname2, testname1]

到此为止,整个流程结束。

分享一篇网上的资料写的很有意思(https://www.cnblogs.com/nnngu/p/9347635.html)

代码优化体会:

场景:需要调用二维接口返回的结果。循环判断结果是否有标志位

原先的做法:在循坏中,重复调用二维接口。

优化:将二维接口提取到循环外,只调用一次就可以。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket是一种在单个TCP连接上进行全双工通信的协议。与HTTP不同,WebSocket允许服务器和客户端在任何时候开始发送数据,并且没有请求和响应之间的延迟。 WebSocket可以用于实时通信,如聊天应用程序、在线游戏和交易系统等。在Spring Boot中,我们可以使用Spring WebSocket来构建WebSocket应用程序。 下面是一个简单的示例,演示如何在Spring Boot中使用WebSocket。 首先,我们需要添加以下依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 接下来,我们需要创建一个WebSocket配置类。该类应该扩展`AbstractWebSocketMessageBrokerConfigurer`类,并重写`registerStompEndpoints()`方法和`configureMessageBroker()`方法。 ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } } ``` 在上面的代码中,我们使用`@EnableWebSocketMessageBroker`注解启用WebSocket消息代理。`registerStompEndpoints()`方法注册一个WebSocket端点,客户端可以使用该端点连接到服务器。`configureMessageBroker()`方法配置消息代理。 接下来,我们需要创建一个控制器类,用于处理WebSocket请求。该类应该使用`@Controller`注解和`@MessageMapping`注解来处理消息。例如,以下控制器类处理`/hello`端点的消息: ```java @Controller public class WebSocketController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); return new Greeting("Hello, " + message.getName() + "!"); } } ``` 在上面的代码中,`@MessageMapping`注解指定要处理的消息的端点。`@SendTo`注解指定要将响应发送到的目标。在这种情况下,响应将被发送到`/topic/greetings`目标。 最后,我们需要创建一个WebSocket客户端。以下是一个简单JavaScript示例,演示如何连接到WebSocket服务器,并发送和接收消息: ```javascript var stompClient = null; function connect() { var socket = new SockJS('/ws'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { console.log('Connected: ' + frame); stompClient.subscribe('/topic/greetings', function(greeting) { showGreeting(JSON.parse(greeting.body).content); }); }); } function sendName() { var name = document.getElementById('name').value; stompClient.send('/app/hello', {}, JSON.stringify({ 'name': name })); } function showGreeting(message) { var greeting = document.createElement('div'); greeting.appendChild(document.createTextNode(message)); document.getElementById('greetings').appendChild(greeting); } ``` 在上面的代码中,`connect()`函数连接到WebSocket服务器,并订阅`/topic/greetings`目标。`sendName()`函数将消息发送到`/app/hello`端点。`showGreeting()`函数显示接收到的消息。 这是一个非常简单的示例,演示如何在Spring Boot中使用WebSocket使用Spring WebSocket,您可以构建复杂的实时应用程序,例如聊天应用程序和在线游戏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值