微服务下不同Websocket Java工具类,服务端和客户端的代码实现

大家好,我是程序员大猩猩。

大家都知道,在程序开发期间,websocket接口是某些程序必不可少的一环。但是websocket跟我们平时开发api又不是系统,有时候我们可以使用Spring自带的websocket框架来实现,有时候又觉得使用其他框架更为便利和高效,那么我在此就给大家介绍一下我们常用的几种websocket实现。

1. Springboot内置websocket

内置websocket是我们经常使用,而且是非常广泛使用的。内置包括基本的websocket创建,而且包含sockJS的实现,以下我们只实现基础的websocket的开发。

首先pom.xml导入websocket starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>a. 内置websocket服务端

新建一个类,注册服务端点,使spring服务知道我们要创建一个websocket端点服务。

@Configuration
public class WebSocketConfig {
    /**
     * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

之后,就是实现socket服务了。

@Slf4j
@ServerEndpoint(value = "/ws/....")
@Component
public class WebSocketServer {
    // 连接
    @OnOpen
    public void onOpen(Session session){}
    // 关闭
    @OnClose
    public void onClose(Session session){}
    // 发生错误
    @OnError
    public void onError(Session session, Throwable e) {}
    // 收到客户端消息
    @OnMessage
    public void onMessage(String json, Session session){}
    // 广播消息
    public <T> void sendAllMessage(T t) throws Exception {
        for (WebSocketServer item : webSocketSet) {
            log.info("【websocket消息】广播消息:" + t);
            synchronized (item.session) {
                item.session.getBasicRemote().sendText(JSON.toJSONString(t));
            }
        }
    }
    // 点对点消息发送
    public <T> void sendOneMessage(String sessionId, T t) throws Exception {
        log.info("开始发送消息 " + sessionMap + ": " + sessionId);
        Session session = sessionMap.get(sessionId);
        if (session != null) {
            try {
                log.info("【websocket消息】单点消息:" + sessionId);
                session.getAsyncRemote().sendText(t.toString());
            } catch (Exception e) {
                log.info("异常信息:{}", e.toString());
            }
        } else {
            log.info("获取不到session,发送消息失败" + sessionMap);
        }
    }
}
  • b.内置websocket客户端
@Configuration
public class WebSocketClientConfig {
    @Bean
    public WebSocketConnectionManager webSocketConnectionManager() {
        WebSocketHandler handler = new WebSocketHandler() {
            @Override
            public void afterConnectionEstablished(WebSocketSession session) throws Exception {
                // 连接建立后的操作
            }
            @Override
            public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                // 处理传输错误的操作
            }
            @Override
            public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
                // 连接关闭后的操作
            }
            @Override
            public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
                // 处理接收到的消息的操作
            }
        };

        WebSocketConnectionManager manager = new WebSocketConnectionManager(new StandardWebSocketClient(), handler, "ws://localhost:8080/ws/...");
        manager.setAutoStartup(true);
        return manager;
    }
}

2. 使用Java-WebSocket实现

Java-WebSocket 是一个开源的、轻量级的WebSocket客户端和服务器库,它遵循Java API规范(JSR 356)来实现WebSocket协议。这个库允许开发者轻松地在Java应用程序中实现WebSocket通信,而不必关心底层的网络细节。

照旧pom.xml导入组件工具包

<dependency>
    <groupId>org.java-websocket</groupId>
    <artifactId>Java-WebSocket</artifactId>
    <version>1.5.4</version>
</dependency>

a. Java-Websocket服务端

@Slf4j
public class WebSocketServer extends WebSocketServer {
    public MyWebSocketServer(int port) {
        super(new InetSocketAddress(port));
    }
    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
       log.info("新的连接: " + conn.getRemoteSocketAddress());
    }
    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        log.info("连接关闭: " + conn.getRemoteSocketAddress());
    }
    @Override
    public void onMessage(WebSocket conn, String message) {
        log.info("收到消息: " + message);
        conn.send("你发送的是: " + message);
    }
    @Override
    public void onError(WebSocket conn, Exception ex) {
        ex.printStackTrace();
    }
    public static void main(String[] args) {
       // 选择一个端口号
        int port = 8887;
        MyWebSocketServer server = new MyWebSocketServer(port);
        server.start();
        log.info("服务器启动在端口: " + port);
    }
}

b. Java-Websocket客户端

public class WebSocketClient extends WebSocketClient {

    public MyWebSocketClient(URI serverUri) {
        super(serverUri);
    }
    @Override
    public void onOpen(ServerHandshake handshakedata) {
        System.out.println("连接开启");
        send("Hello, Server!"); // 向服务器发送消息
    }
    @Override
    public void onMessage(String message) {
        System.out.println("收到消息: " + message);
    }
    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("连接关闭: " + reason);
    }
    @Override
    public void onError(Exception ex) {
        ex.printStackTrace();
    }
    public static void main(String[] args) {
        try {
            WebSocketClient client = new MyWebSocketClient(new URI("ws://localhost:8887"));
            client.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
}

3. 使用okhttp3实现

okhttp3应该是在android端实现的利器,虽然本人不具备android原生的开发,但是接触okhttp3之后,感觉它应该也是一个非常好的通信框架。而且它也支持socket开发。

但是,我们要知道okhttp3是不提供websocket服务端创建的。

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.9.3</version>
</dependency>

okhttp3客户端实现

public class OkHttpWebSocketClient {

    private final OkHttpClient client = new OkHttpClient();

    public void start() {
        Request request = new Request.Builder()
                .url("ws://localhost:8080/ws/...")
                .build();
        WebSocketListener webSocketListener = new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                System.out.println("WebSocket opened");
                 // 连接打开后发送消息
                webSocket.send("Hello, Server!");
            }
            @Override
            public void onMessage(WebSocket webSocket, String text) {
                System.out.println("Received message: " + text);
            }
            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                System.out.println("WebSocket closing: " + reason);
            }
            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                t.printStackTrace();
            }
        };
        client.newWebSocket(request, webSocketListener);
    }
    public static void main(String[] args) {
        new OkHttpWebSocketClient().start();
    }
}

4. 使用Jetty时限

Jetty是一个开源的、基于Java的HTTP服务器和Servlet容器。

<dependencies>
    <dependency>
        <groupId>org.eclipse.jetty.websocket</groupId>
        <artifactId>websocket-server</artifactId>
        <version>9.4.43.v20210629</version> 
      </dependency>
</dependencies>

a. Jetty服务端

首先我们需要设置一个websocket的端点

@Slf4j
@WebSocket
public class MyWebSocketEndpoint {

    @OnWebSocketConnect
    public void onConnect(Session session) throws Exception {
        log.info("New connection: " + session.getRemoteAddress().getAddress());
        session.getRemote().sendString("Hello, Client!");
    }

    @OnWebSocketMessage
    public void onMessage(Session session, String message) throws Exception {
        log.info("Received message: " + message);
        session.getRemote().sendString("You said: " + message);
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        log.info("Connection closed: " + reason);
    }
}

然后我们在启动服务时,启动socket端点

Server server = new Server(8080);

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);

ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
wscontainer.addEndpoint(MyWebSocketEndpoint.class);

server.start();
server.join();

b. Jetty客户端

设置端点

@Slf4j
@WebSocket
public class MyWebSocketClientEndpoint {

    @OnWebSocketConnect
    public void onConnect(Session session) throws Exception {
        log.info("Connected to server");
        session.getRemote().sendString("Hello, Server!");
    }

    @OnWebSocketMessage
    public void onMessage(String message) {
        log.info("Received message: " + message);
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        log.info("Connection closed: " + reason);
    }
}

连接服务端

public class JettyWebSocketClient {

    public static void main(String[] args) throws Exception {
        WebSocketClient client = new WebSocketClient();
        try {
            client.start();

            URI uri = new URI("ws://localhost:8080/myWebSocketEndpoint");
            ClientEndpointConfig config = ClientEndpointConfig.Builder.create().build();
            Session session = client.connectToServer(new MyWebSocketClientEndpoint(), config, uri);
            // 等待连接关闭
            session.getCloseFuture().get();
        } finally {
            client.stop();
        }
    }
}

以上四种工具类连接方式应该是我们经常用到的,但是不防我们程序员大神开源了很多websocket库,并且很好用。

假如有好用的可以给我留言,大家一起探讨使用,谢谢。

猜你喜欢

转载自blog.csdn.net/t610654893/article/details/139023175