websocket入门开发

1、引入pom
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
</dependency>
2、配置webSocket类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
3、编写webSocket服务
@ServerEndpoint(value = "/api/applet/websocket")
@Component
public class AppletWebSocket {
    /**
     * 静态变量,用来记录当前在线连接数
     */
    private volatile static int onlineCount = 0;

    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     */
    private volatile static CopyOnWriteArraySet<AppletWebSocket> webSocketSet = new CopyOnWriteArraySet<AppletWebSocket>();

    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 用户标识
     */
    private Long userId;

    /**
     * 连接建立成功调用的方法
     * 每次新建链接时,查询该用户的状态
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token) throws IOException, EncodeException {
        this.session = session;
        webSocketSet.add(this);
        addOnlineCount();
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        subOnlineCount();
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
          sendMessage(message));
        } catch (IOException e) {
          System.out.println(e);
        }
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message) throws IOException {
        for (AppletWebSocket item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        AppletWebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        AppletWebSocket.onlineCount--;
    }

    public CopyOnWriteArraySet<AppletWebSocket> getWebSocketSet() {
        return webSocketSet;
    }

    public Long getUserId() {
        return userId;
    }

    public Session getSession() {
        return session;
    }
}
4、测试接口是否正常

打开在线测试网址:http://coolaf.com/tool/chattest

输入自己的服务地址,记得url是以ws://开头的

测试正常即可在自己的程序中引用,具体已业务规则为准。

image-20210728161903644

5、个人建议

AppletWebSocket类中需要加入用户标识,方便系统主动推送信息时,区分用户。

可启动多个socket服务。

6、经历的坑

1)本地可以正常连接,发布到服务器显示404

请按照一下情况检查:

a. nginx配置检查

location /websocket/applet {
  #websocket 配置
  proxy_connect_timeout 4s;
  proxy_read_timeout 7200s; #超过7200秒(两小时)内没通讯则断连
  proxy_send_timeout 12s;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_pass http://localhost:8587/websocket/applet;
}

b. 请ping下你的域名,检查是否指向你服务器的ip地址

win + R 打开dos窗口
ping 你的域名

我就是这种情况,一直报404,但是我其他接口没问题,检查之后发现是我的www.51bishe.site使用了cdn加速,指向的是加速的地址,导致一致报404.

如果使用域名不行,可以使用ip地址的方式进行测试,缩小排查范围。

c. 如果你的服务器用的是https的加密协议,记得你的soket请求地址是以wss://开头。

本文由博客一文多发平台 OpenWrite 发布!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值