websocket简单的java代码示例

1.说明

关于websocket的介绍,有许多的文章都讲的很详细也很好,这里就不再赘述。这里提供websocket的java代码简单实现,包括js的客户端和后台java的服务端,后端使用TomcatWebsocket和SpringWebSocket两种方式,实现tcp连接和通信,以供大家学习参考。

2.环境准备

后端使用SpringBoot加Maven构建项目,前端直接使用html加js实现。请先准备一个能够跑起来的SpringBoot后端项目。
添加websocket的maven依赖(pom.xml):

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

3.TomcatWebsocket后端代码

3.1 websocket配置类

将这个配置类加入项目中。


/**
 * 配置后会自动注册所有的 @ServerEndpoint,一定不要忘记这个配置类
 * @author 广大网友
 */
@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

3.2 websocket服务端代码

@ServerEndpoint注解添加服务端路径 path ,客户端在建立连tcp接时就使用:var ws = new WebSocket(“ws://你的后台项目地址/path”); 建立连接。需要携带参数时:var ws = new WebSocket(“ws://你的后台项目地址/path?accessToken=某某”) 建立连接。

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;

/**
 * TomcatWebSocket服务端
 *
 * @author 别人家的孩子e
 */

@Component
@ServerEndpoint("/test/tomcatWebsocket")
public class WebSocketEndPoint {


    /**
     * 注意,多个会话会公用这一个num对象
     */
    private static Integer num = 1;

    /**
     * tcp连接建立时触发
     */
    @OnOpen
    public void onOpen(Session session) throws IOException {
        System.out.println("会话:" + session.getId() + "的tcp连接已建立。");
        //获得路径中携带的参数,通常为认证token
        List<String> accessToken = session.getRequestParameterMap().get("accessToken");
        //注意判路径中是否有携带参数
        if (accessToken != null && accessToken.size() > 0){
            String token = accessToken.get(0);
            System.out.println("会话人token:" + token);
        }else {
            System.out.println("会话人无访问token!!!");
        }
    }

    /**
     * 接收到消息时触发
     */
    @OnMessage
    public String onMessage(Session session, String message) {
        //这里假定在访问url中都携带accessToken
        List<String> accessToken = session.getRequestParameterMap().get("accessToken");
        String token = accessToken.get(0);
        System.out.println("服务端接收的消息:" + message + "---消息属于会话:" + session.getId() + "。token:" + token);
        return "服务端收到第" + num++ + "条消息";
    }

    /**
     * 遇到错误时触发
     */
    @OnError
    public void onError(Throwable t) {
        System.out.println("webSocket遇到问题:");
        t.printStackTrace();
    }

    /**
     * tcp连接关闭时触发
     */
    @OnClose
    public void onClose(Session session, CloseReason reason) {
        //这里假定在访问url中都携带accessToken
        List<String> accessToken = session.getRequestParameterMap().get("accessToken");
        String token = accessToken.get(0);
        System.out.println("会话:" + session.getId() + "的连接已关闭。token:" + token);
        num = 1;
    }

}

4.SpringWebSocket后端代码

实现方式和TomcatWebSocket略有区别,而效果相同,前端代码改一下访问地址就ok。

4.1 添加拦截器

SpringWebsocket需要使用拦截器获取请求路径中的参数。

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 因为 WebSocketSession 无法获得 ws 地址上的请求参数,所以只好通过该拦截器,获得 accessToken 请求参数,设置到 attributes 中。
 *
 * 也可以 implements HandshakeInterceptor
 * @author 别人家的孩子e
 */
@Component
public class WebSocketShakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 从请求路径中获得 accessToken
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request;
            HttpServletRequest servletRequest = serverRequest.getServletRequest();
            attributes.put("accessToken", servletRequest.getParameter("accessToken"));
        }
        // 调用父方法,继续执行逻辑
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

}

4.2 添加消息处理器

对应TomcatWebSocket的服务端点(WebSocketEndPoint)。但是访问路径在4.3中配置。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * 处理连接和消息
 *
 * @author 别人家的孩子e
 */
@Component
public class DemoWebSocketHandler extends TextWebSocketHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 对应 open 事件
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.info("[afterConnectionEstablished][session({}) 接入]", session);
        // 解析 accessToken
        String accessToken = (String) session.getAttributes().get("accessToken");
        System.out.println("连接建立,token:" + accessToken);
    }

    /**
     * 对应 message 事件
     */
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage textMessage) throws Exception {
        logger.info("[handleMessage][session({}) 接收到一条消息({})]", session, textMessage);
        System.out.println("textMessage:" + textMessage.toString());
        System.out.println("textMessage.getPayload():" + textMessage.getPayload());
        session.sendMessage(new TextMessage("服务端收到,over。"));
    }

    /**
     * 对应 close 事件
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        logger.info("[afterConnectionClosed][session({}) 连接关闭。关闭原因是({})}]", session, status);
        System.out.println(session.getAttributes().get("accessToken").toString() + "的连接已关闭。");
    }

    /**
     * 对应 error 事件
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        logger.info("[handleTransportError][session({}) 发生异常]", session, exception);
        System.out.println("连接异常!!");
    }

}

4.3 添加配置

将前面定义的拦截器和消息处理器添加到配置中。


import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**
 * 、@EnableWebSocket :开启 springwebsocket
 *
 * @author 别人家的孩子e
 */
@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {

    /**
     * addHandler:配置处理器
     * addInterceptors:配置拦截器
     * setAllowedOrigins: 设置跨域
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry
                .addHandler(new DemoWebSocketHandler(), "/test/springWebsocket")
                .addInterceptors(new WebSocketShakeInterceptor())
                .setAllowedOrigins("*");
    }
}

5.前端代码

直接c走。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="referrer" content="no-referrer">
    <title>websocket案例</title>
<style>
body{
    background-image: url("https://wallpaperm.cmcm.com/7aee1626bc5e2d89129aa61f6b6f2582.jpg");
    background-color: lightyellow;
    background-size: cover;
}
#sendMessage{
    height: 30px;
    color:brown;
}
#closeWebSocket{
    height: 30px;
    color: red;
}
#show{
    background-color: antiquewhite;
    width: 500px;
    margin: auto;
    text-align: left;
    opacity: 0.7;
}
</style>
</head>
<body>
    <div style="width: 100%;text-align: center;color:black;background-color: antiquewhite;opacity: 0.7;">
       <h1>websocket测试用例</h1> 
       <h2 style="color: red;">记得给我点个赞!!!</h2>
       <button id="sendMessage">点击发送消息</button>
       <button id="closeWebSocket">点击关闭tcp连接</button>
       <div id="show">
            <h4 id="onopen">onopen:</h4>
            <h4 id="onmessage">onmessage:</h4>
            <h4 id="onerror">onerror:</h4>
            <h4 id="onclose">onclose:</h4>
       </div>
    </div>

    <script>
        //和websocket服务端建立tcp连接,刷新页面触发
        var ws = new WebSocket("ws://127.0.0.1:8080/test/tomcatWebsocket?accessToken=秀儿"); //连接tomcatWebsocket
		//var ws = new WebSocket("ws://127.0.0.1:8080/test/springWebsocket?accessToken=秀儿"); //连接springWebsocket
		
        /* websocket客户端部分API如下 */

        // 1.连接建立时触发
        ws.onopen = function(){
            //send方法用于向服务器发送消息
            ws.send('这是客户端在tcp连接建立后发送的消息');
        let onopen = document.getElementById('onopen');
        onopen.innerText = 'onopen: ' + "webSocket客户端已和服务端创建tcp连接。";
        }; 
        // 2.接收到webSocket服务端消息就触发
        ws.onmessage = function(evt){
            let onmessage = document.getElementById('onmessage');
            onmessage.innerText = 'onmessage: ' + evt.data;
        }; 
        //3.出现异常时触发
        ws.onerror = function(evt){
            let onerror = document.getElementById('onerror');
            onerror.innerText = 'onerror: ' + "webSocket发生异常!";
        };
        // 4.连接关闭时触发
        ws.onclose = function(evt){
            let onclose = document.getElementById('onclose');
            onclose.innerText = 'onclose: ' + "webSocket的tcp连接已关闭。";
        }; 
        //点击发送消息按钮
        let sendMessageButton = document.getElementById('sendMessage');
        sendMessageButton.onclick = function () {
            ws.send('客户端发送了消息到服务器端');
        }
        //点击关闭tcp连接按钮
        let closeButton = document.getElementById('closeWebSocket');
        closeButton.onclick = function(){
            //关闭websocket的tcp连接
            ws.close();
        }
    </script>
</body>
</html>

后端项目跑起来就能实现tcp通信了。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单Java WebSocket示例代码: Server端: ``` import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; @ServerEndpoint("/echo") public class EchoServer { @OnOpen public void onOpen(Session session) { System.out.println("WebSocket opened: " + session.getId()); } @OnMessage public void onMessage(String message, Session session) throws IOException { System.out.println("Message received: " + message); session.getBasicRemote().sendText(message); } @OnClose public void onClose(Session session) { System.out.println("WebSocket closed: " + session.getId()); } @OnError public void onError(Throwable t) { System.out.println("WebSocket error: " + t.getMessage()); } } ``` Client端: ``` import javax.websocket.*; import java.io.IOException; import java.net.URI; import java.util.Scanner; @ClientEndpoint public class EchoClient { private Session session; @OnOpen public void onOpen(Session session) { System.out.println("WebSocket opened: " + session.getId()); this.session = session; } @OnMessage public void onMessage(String message) { System.out.println("Message received: " + message); } @OnClose public void onClose(Session session) { System.out.println("WebSocket closed: " + session.getId()); } @OnError public void onError(Throwable t) { System.out.println("WebSocket error: " + t.getMessage()); } public void send(String message) throws IOException { session.getBasicRemote().sendText(message); } public static void main(String[] args) throws Exception { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); Session session = container.connectToServer(EchoClient.class, URI.create("ws://localhost:8080/echo")); EchoClient client = (EchoClient) session.getUserProperties().get("client"); Scanner scanner = new Scanner(System.in); while (true) { String message = scanner.nextLine(); client.send(message); } } } ``` 这个示例中定义了一个简单WebSocket服务端和客户端,服务端接收客户端发送的消息并返回相同的消息,客户端可以发送消息到服务端。使用Java WebSocket API非常简单,只需要使用注解标记需要处理的方法即可。在服务端,@ServerEndpoint注解标记WebSocket的URI,@OnOpen、@OnMessage、@OnClose和@OnError注解分别标记WebSocket的生命周期、接收消息、关闭WebSocket和处理错误的方法。在客户端,@ClientEndpoint注解标记WebSocket的URI,注解中的URI可以是Web服务的URL或WebSocket的URL。使用WebSocketContainer.connectToServer方法连接到WebSocket服务器并获取Session对象,然后使用Session.getBasicRemote().sendText方法发送消息。 以上代码仅供参考,实际应用中可能需要更多的细节处理和异常处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值