Java-springboot集成websocket

一、服务端

  1. 服务端依赖
        <!--即时通讯服务端-->
        <dependency>
            <!-- websocket -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <!-- fastjson -->
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.4</version>
        </dependency>
  1. 创建配置类
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
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}
  1. 创建工具类
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class WebSocketMapUtil {

    public static ConcurrentMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();

    public static void put(String key, WebSocketServer webSocketServer){
        webSocketMap.put(key, webSocketServer);
    }

    public static WebSocketServer get(String key){
         return webSocketMap.get(key);
    }

    public static void remove(String key){
         webSocketMap.remove(key);
    }
 
    public static Collection<WebSocketServer> getValues(){
        return webSocketMap.values();
    }
}
  1. 创建服务类
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import cn.hutool.json.JSONObject;
import org.springframework.stereotype.Component;

@Component
@ServerEndpoint(value = "/websocket/service")
public class WebSocketServer {

    private Session session;

    /**
     * 连接建立后触发的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        WebSocketMapUtil.put(session.getId(), this);
    }

    /**
     *连接关闭后触发的方法
     */
    @OnClose
    public void onClose() {
        //从map中删除
        WebSocketMapUtil.remove(session.getId());
    }

    /**
     *接收到客户端消息时触发的方法
     */
    @OnMessage
    public void onMessage(String params, Session session) throws Exception {
        //获取服务端到客户端的通道
        WebSocketServer myWebSocket = WebSocketMapUtil.get(session.getId());
        String result = "收到来自" + session.getId() + "的消息" + params;
        //返回消息给Web Socket客户端(浏览器)
        myWebSocket.sendMessage(1,"成功!", result);
    }

    public void sendMessage(int code, String msg, Object data) throws IOException {
        JSONObject result = new JSONObject();
        result.put("code", code);
        result.put("msg", msg);
        result.put("data", data);
        this.session.getBasicRemote().sendText(result.toString());
    }

    /**
     * 向指定客户端发送消息
     * @param uid 客户端id
     */
    public synchronized void send(String uid){
        try {
            WebSocketServer myWebSocket = WebSocketMapUtil.get(uid);
            myWebSocket.sendMessage(1,"ok","null");
        }catch (Exception e){
            e.getMessage();
        }
    }

}
  1. 创建控制器类
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
@RequestMapping("/web/socket")
public class WebSocketController {

    @Resource
    private WebSocketServer myWebSocket;

    /**
     * 向客户端发送消息
     * @param uid 客户端连接id
     * @return
     */
    @GetMapping("/send")
    public String send(String uid){
        myWebSocket.send(uid);
        return "OK";
    }
}

分别引入对应的类

二、 客户端
创建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>即时通讯</title>
</head>

<body>
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body>

<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
    if ('WebSocket' in window) {
        // websocket = new WebSocket("即时通讯协议://服务器:服务端端口/服务类的路由");
        websocket = new WebSocket("ws://127.0.0.1:8080/websocket/service");
    } else {
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function() {
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(event) {
        setMessageInnerHTML("连接成功");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event) {
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function() {
        setMessageInnerHTML("关闭连接");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function() {
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket() {
        websocket.close();
    }

    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

三、测试

  1. 用浏览器打开index.html文件
    在这里插入图片描述

调用控制器类的接口 传入指定客户端id即可对指定客户端发送消息:

在这里插入图片描述

Java作为客户端

  1. 添加需要的依赖
		<!--即时通讯客户端-->
        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.8</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!--轻量级别maven工程-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.6</version>
        </dependency>
  1. 客户端服务
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.stereotype.Component;
import java.net.URI;
import java.net.URISyntaxException;

@Component
public class WsClient {

    /**
     * 获取客户端连接实例
     * @param uri
     * @return
     */
    public WebSocketClient getClient(String uri) {

        try {

            //创建客户端连接对象
            WebSocketClient client = new WebSocketClient(new URI(uri), new Draft_6455()) {

                /**
                 * 建立连接调用
                 * @param serverHandshake
                 */
                @Override
                public void onOpen(ServerHandshake serverHandshake) {
                    System.out.println("建立连接");
                }

                /**
                 * 收到服务端消息调用
                 * @param s
                 */
                @Override
                public void onMessage(String s) {
                    System.out.println("收到来自服务端的消息:" + s);
                }
                /**
                 * 断开连接调用
                 */
                @Override
                public void onClose(int i, String j, boolean k) {
                    System.out.println("关闭连接:::" + "i = " + i + ":::j = " + j + ":::k = " + k);
                }
                /**
                 * 连接报错调用
                 * @param e
                 */
                @Override
                public void onError(Exception e) {
                    System.out.println("报错了:::" + e.getMessage());
                }
            };
            //请求与服务端建立连接
            client.connect();
            //判断连接状态,0为请求中  1为已建立  其它值都是建立失败
            while (client.getReadyState().ordinal() == 0) {
                try {
                    Thread.sleep(200);
                } catch (Exception e) {
                    System.out.println("延迟操作出现问题,但并不影响功能");
                }
                System.out.println("连接中。。。");
            }
            client.send("客户端发送请求");
        } catch (URISyntaxException e) {
            System.out.println(e.getMessage());
        }
        return null;
    }
}
  1. 连接服务端

public class DemoApplication {
    public static void main(String[] args){
        WsClient javaClient = new WsClient();
        javaClient.getClient("ws://127.0.0.1/websocket/service");
    }
}


目录结构(这里使用的maven工程)
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值