webSocketDemo

GitHub demo地址
https://github.com/Smartxiaowang/websocketdemo.git

websocketdemo

服务端接口文档

接口rul 参数 返回值 类型 描述
send msg(String) 发送人数(String) GET 给所有连接的用户发送通知
send uid(String),msg(String) 发送用户与信息(String) Post 给单个用户发送通知
getstu uid(String) 连接状态(String) POST 获取连接
Logout uid(String) info,data,current_time,status,code Get 断开此用户连接

客户端socket状态

socket.on()监听的事件:

connect:连接成功
connecting:正在连接
disconnect:断开连接
connect_failed:连接失败
error:错误发生,并且无法被其他事件类型所处理
message:同服务器端message事件
anything:同服务器端anything事件
reconnect_failed:重连失败
reconnect:成功重连
reconnecting:正在重连
当第一次连接时,事件触发顺序为:connecting->connect;当失去连接时,事件触发顺序为:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。

一、服务端连接配置

//通过Java类的模式给SocketIo赋值
ws:
  port: 8888
  title: arduino服务器
  host: 0.0.0.0
  boss-count: 1
  work-count: 100
  allow-custom-requests: true
  upgrade-timeout: 10000
  ping-timeout: 60000
  ping-interval: 25000
//yml
      
@Data
@ConfigurationProperties("ws")
public class AppProperties {
    /**
     * title
     */
    private String title;

    /**
     * host
     */
    private String host;

    /**
     * port
     */
    private Integer port;

    /**
     * bossCount
     */
    private int bossCount;

    /**
     * workCount
     */
    private int workCount;

    /**
     * allowCustomRequests
     */
    private boolean allowCustomRequests;

    /**
     * upgradeTimeout
     */
    private int upgradeTimeout;

    /**
     * pingTimeout
     */
    private int pingTimeout;

    /**
     * pingInterval
     */
    private int pingInterval;
}
//Properties



//Configuration
@Configuration
@EnableConfigurationProperties({
        AppProperties.class,
})
public class AppConfiguration {

    @Scope("prototype")
    @Bean
    public SocketIOServer socketIoServer(AppProperties appProperties) {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setSocketConfig(socketConfig);
        config.setHostname(appProperties.getHost());
        config.setPort(appProperties.getPort());
        config.setBossThreads(appProperties.getBossCount());
        config.setWorkerThreads(appProperties.getWorkCount());
        config.setAllowCustomRequests(appProperties.isAllowCustomRequests());
        config.setUpgradeTimeout(appProperties.getUpgradeTimeout());
        config.setPingTimeout(appProperties.getPingTimeout());
        config.setPingInterval(appProperties.getPingInterval());
        return new SocketIOServer(config);
    }

Spring boot get bean 工具类

package com.coding.config;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }
    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

多用户启动

@PostConstruct
//启动的时候会被调用一次
    private void autoStart() {
        log.info("start ws");
        socketIOServer.addConnectListener(client -> {
            log.info("check success");
            CLIENT_MAP.put(client.getSessionId(), client);
            log.info("uid:{}", client.getSessionId());
        });
        //退出时切断
        socketIOServer.addDisconnectListener(client -> {
            CLIENT_MAP.remove(client.getSessionId());
            client.disconnect();
            log.info("移除client:{}", client.getSessionId());
        });
        socketIOServer.start();
        log.info("start finish");
    }

    @PreDestroy
    private void onDestroy() {
        if (socketIOServer != null) {
            socketIOServer.stop();
        }
    }

多用户消息

public int sendMsg(Object demo) {
        CLIENT_MAP.forEach((key, value) -> {
            value.sendEvent("server_event", demo);
            log.info("发送数据成功:{}", key);
        });
        return CLIENT_MAP.size();

单用户消息

public String sendOneMsg(Map<String,String> map) {
        UUID uid = UUID.fromString(map.get("uid"));
        map.remove("uid");
        Object demo = map;
        SocketIOClient client = CLIENT_MAP.get(uid);
        client.sendEvent("server_event", demo);
        log.info("发送数据成功:{}", map.get("msg"));
        String mssg = "给此用户 " + uid + " 发送:" + map.get("msg");
        return mssg;
    }

挂断

public HashMap<String,String> Logout(UUID uid) {
        HashMap<String,String> date = new HashMap<>();
        log.info("移除uid:{}",uid);
        CLIENT_MAP.remove(uid);
        date.put("info","0");
        date.put("data"," ");
        date.put("current_time"," ");
        date.put("status","已关闭连接");
        date.put("code"," ");
        return date;
    }

客户端

点击获取连接状态

 function btn(){
        const socket = io('http://127.0.0.1:8888');
        let txt
        socket.on('connect', () => {
            //连接成功后 返回状态
            txt =  document.getElementById("code")
            txt.innerHTML = socket.id
            $.ajax({
                type: "POST", // 以post方式发起请求
                url: "http://localhost:8080/getstu", // 你的请求链接
                data: { // 提交数据
                    "uid": socket.id, // 前者为字段名,后者为数据
                },
                success(info) {
                    var txt =  document.getElementById("status")
                    txt.innerHTML=info.info
                }
            })
            socket.on('server_event', data => {
                $("#data").html(data.msg);
                $("#current_time").html(data.date);
            });
        });
    }

点击断开

function btns() {
        var txt =  document.getElementById("code").innerText
        $.ajax({
            type: "GET", // 以post方式发起请求
            url: "http://localhost:8080/Logout", // 你的请求链接
            data: { // 提交数据
                "uid": txt, // 前者为字段名,后者为数据
            },
            success(info) {
                    var txt =  document.getElementById("status")
                    txt.innerHTML=info.status
                    var txt1 =  document.getElementById("data")
                    txt1.innerHTML=info.data
                    var txt2 =  document.getElementById("current_time")
                    txt2.innerHTML=info.current_time
                    var txt3 =  document.getElementById("code")
                    txt3.innerHTML=info.code
            }
        })
    }
原文地址:https://www.cnblogs.com/laowt/p/14774916.html