首页 > 其他分享 >websocket的简单使用

websocket的简单使用

时间:2022-08-19 14:22:46浏览次数:84  
标签:webSocketMap websocket 简单 WebSocket 使用 import message public

  程序git:https://gitee.com/juncaoit/websocketpro

 

1.引入pom

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

 

2.@ServerEndpoint

  @ServerEndpoint注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
  注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端

   /**
     * 会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     * 要注意,如果使用独立的servlet容器,
     * 而不是直接使用springboot的内置容器,
     * 就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
      return new ServerEndpointExporter();
    }

 

3.服务器方法

package com.jun.send.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@Slf4j
@ServerEndpoint("/webSocket/{category}")
public class WebSocketServer {
    /**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static int onlineCount = 0;
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。
     */
    public static ConcurrentHashMap<WebSocketServer, String> webSocketMap = new ConcurrentHashMap<>();
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 连接建立成
     * 功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("category") String category) {
        this.session = session;
        webSocketMap.put(this, category);
        log.info("【websocket消息】有新的连接,总数:{}", webSocketMap.size());
        sendInfo("连接成功");
    }

    /**
     * 连接关闭
     * 调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketMap.remove(this);
        log.info("【websocket消息】连接断开,总数:{}", webSocketMap.size());
    }

    /**
     * 收到客户端消
     * 息后调用的方法
     *
     * @param message 客户端发送过来的消息
     **/
    @OnMessage
    public void onMessage(String message) {
        log.info("【websocket消息】收到客户端发来的消息:{}", message);
    }


    /**
     * @param error
     */
    @OnError
    public void one rror(Throwable error) {
        log.error("发和错误,原因:" + error.getMessage());
        error.printStackTrace();
    }


    /**
     * 实现服务
     * 器主动推送
     */
    public void sendMessage(String message, String category) {
        for (Map.Entry<WebSocketServer, String> entry : webSocketMap.entrySet()) {
            WebSocketServer webSocketServer = entry.getKey();
            log.info("【websocket消息】广播消息,category={}, message={}", category, message);
            try {
                webSocketServer.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 发送自定
     * 义消息
     **/
    public void sendInfo(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

 

4.job定时推送给前端数据

package com.jun.send.job;

import com.alibaba.fastjson.JSON;
import com.jun.send.model.WpDataInfo;
import com.jun.send.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class SendMessageJob {
    @Resource
    private WebSocketServer webSocketServer;

    @Scheduled(cron = "0 */2 * * * ?")
    public void sendMessage() {
        ConcurrentHashMap<WebSocketServer, String> webSocketMap = WebSocketServer.webSocketMap;
        if (webSocketMap.size() <= 0) {
            log.info("没有session,不进行处理,不进行推送数据");
            return;
        }

        WpDataInfo wpDataInfo = new WpDataInfo();
        wpDataInfo.setDeviceNo("34-ME-01");
        wpDataInfo.setCreateTime("2022-08-17 00:00:00");
        webSocketServer.sendMessage(JSON.toJSONString(wpDataInfo), "wp");
        log.info("发送的数据成功");
    }

}

 

5.前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket client</title>
    <script type="text/javascript">
        var socket;
        if (typeof (WebSocket) == "undefined"){
            alert("This explorer don't support WebSocket")
        }

        function connect() {
            //Connect WebSocket server
            socket =new WebSocket("ws://127.0.0.1:8099/webSocket/wp");
            //open
            socket.onopen = function () {
                alert("WebSocket is open");
            }
            //Get message
            socket.onmessage = function (msg) {
                alert("Message is " + msg);
            }
            //close
            socket.onclose = function () {
                alert("WebSocket is closed");
            }
            //error
            socket.onerror = function (e) {
                alert("Error is " + e);
            }
        }

        function close() {
            socket.close();
        }

        function sendMsg() {
            socket.send("This is a client message ");
        }
    </script>
</head>
<body>
    <button onclick="connect()">connect</button>
    <button onclick="close()">close</button>
    <button onclick="sendMsg()">sendMsg</button>
</body>
</html>

 

6.测试

  

 

标签:webSocketMap,websocket,简单,WebSocket,使用,import,message,public
From: https://www.cnblogs.com/juncaoit/p/16601826.html

相关文章

  • 一次正则表达式的使用记录
    背景今天老大让我解决一个问题,这个问题的场景是后台管理商品模块编辑商品时,商品信息的商品详情无法回显,但是不是所有商品都不能回显,有的能回显,有的不能回显.定位问......
  • 【Python】使用requests_html解析HTML页面
    1、官网https://pypi.org/project/requests-html/ 2、githubhttps://github.com/kennethreitz/requests-html 3、安装pipinstallrequests-html  4、使用......
  • biomaRt使用 | 同源基因名转换 | 人鼠同源基因ID
     这个要严谨一点,众所周知,小鼠是小写,人是大写,以前为了方便都是直接一个toupper函数完成转换,但这样做实在是太粗糙了,大概有三分之一的基因会丢失。我简单统计了一下:人鼠......
  • Hive使用Load加载数据操作
    Hive使用Load进行加载数据操作分为两种情况。第一种是文件在虚拟机本地,另一种是文件在HDFS文件系统根目录。对应两种情况,底层也会进行复制、移动操作。虚拟机本地加载这......
  • Bika LIMS 开源LIMS集—— SENAITE的使用(仪器管理的使用)
    设备类型对设备进行分类。设备设备台账。设备管理中可设置Validation、Calibration、QCSample等质控信息以及仪器数据采集信息。......
  • 使用pip 安装requirements.txt中所需要的包
    使用pip安装requirements.txt中所需要的包pipinstall-rrequirements.txt使用 pipfreeze 会输出所有在本地已安装的包(但不包括 pip、wheel、setuptools 等自......
  • 无网络使用本地maven仓库配置,构建上传sonarqube进行代码检查
    #前提需要本地仓库下存在项目的所有依赖包1.mavensettings.xml文件配置。如果idea和本地mvn环境使用的settings.xml路径不一致。则需要同步修改。<!--#前提需要本......
  • Git使用教程
    Git使用教程说明:本文中的表述存在主观理解,准确说法请移步官方文档本文的内容仅为作者常用的功能介绍且在各IDE中会有图形化操作方法作为替代,例如VS,JetBrains系列的......
  • 一个简单的服务
    constexpress=require('express');constapp=express();constport=process.env.PORT||3000;app.get('/',(req,res)=>{res.send('HelloWorld!!!');......
  • java:菜单的使用
    1.JMenuBar菜单条2.JMenu菜单3.JMenuItem菜单项菜单条包含菜单,每个菜单有包含一些菜单项。菜单也可以修改布局,默认是流式布局,可自定义。直接上一段代码演示:1impor......