Springboot java websocket ws quick start

Learning without thinking means nothing, thinking without learning means nothing.

1. Background introduction

Most of java is doing the server side. The main process is that the client initiates an http request, the server receives the request, and then responds to the data.
Insert picture description here
If the server wants to send data to the client at this time, it is more common to have

  • Round sequence: That is, the client keeps requesting the data from the server, so the server is under pressure
  • Long connection: Maintaining a persistent connection in the form of an iframe puts a lot of pressure on the server.
  • webSocket: This is what this article will talk about. After the connection is established by TCP, two-way communication can be achieved.
    Insert picture description here

Second, best practices

2.1 Introduce dependencies

		 <!-- spring boot 的依赖 -->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
         <!-- websocket 的依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

2.2 Add annotation @EnableWebSocket and inject ServerEndpointExporter on the startup class

@SpringBootApplication
@EnableWebSocket
@MapperScan("com.example.demo.dao")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
	
	 /**
     * 初始化Bean,它会自动注册使用了 @ServerEndpoint 注解声明的 WebSocket endpoint
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
 }

2.3 Write server-side instance

package com.example.demo.websocket;

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

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Classname WebSocketTest
 * @Description webSocket 测试类
 * @Date 2020/11/27 13:23
 * @Created by dongzhiwei
 */
@ServerEndpoint(value="/websocket/{id}")
@Slf4j
@Component
public class WebSocketTest {

    private static int onlineCount = 0;
    private static Map<String, WebSocketTest> webSocketMap = new ConcurrentHashMap<>();
    private Session session;
    private String id;

    /**
     * 用户第一次建立连接的时候执行的方法
     * @param id
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session){
        this.id = id;
        this.session = session;
        if (!webSocketMap.containsKey(id)) {
            //没有建立连接的
            webSocketMap.put(id, this);
            //注意并发
            addOnlineCount();
        }
        log.info("用户"+id+"连接上webSocket,当前连接人数为"+getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(this.id)){
            webSocketMap.remove(this.id);
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:"+id+",当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("用户"+this.id+"发送信息:"+message);
    }

    /**
     * 发生错误的时候调用的方法
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:"+this.id+",原因:"+error.getMessage());
        error.printStackTrace();
    }

    /**
     * 向执行某个任务的客户端发送消息
     */
    public void sendMessage(String message){
        this.session.getAsyncRemote().sendText(message);
    }

    /**
     * 向用户id为userId的用户推送消息
     * */
    public static void sendInfo(String message,String id){
        log.info("发送消息到:"+id+",报文:"+message);
        if(id != null && webSocketMap.containsKey(id)){
            webSocketMap.get(id).sendMessage(message);
        }else{
            log.error("用户"+id+",不在线!");
        }
    }

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

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

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


}

2.4 Test connection

Start the service, establish a socket connection based on the ip address and port, click here to test online
Insert picture description here

Three, summary

In fact, deploying ws on an http server will have no problem access and no problems. They are two different protocols, one http protocol and one websocket protocol. We can get the latest news in real time similar to chat rooms and browsers. Use this ws protocol. No matter how you use it, it is just a tool, whether it is applicable in this scenario.

Guess you like

Origin blog.csdn.net/hgdzw/article/details/110231603