spring中利用websocket打造最简易的双向通讯

spring中利用websocket打造最简易的双向通讯

首先引入pom,该pom根据spring-boot的版本自动选择

fastjson用于将websocket传输的消息体序列化为对象

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.50</version>
</dependency>

新建WebSocketServer.java

① @ServerEndpoint标注对应websocket的链接地址,如以下前端通过ws://localhost:8080/test/1连接

② onlineSessionClientMap存储当前在线客户端集合

@ServerEndpoint(value = "/test/{id}")
@Slf4j
@Component
public class WebSocketServer {

    //在线客户端集合
    private static final Map<String, Session> onlineSessionClientMap = new ConcurrentHashMap<>();

    /**
     * 连接创建成功
     *
     * @param id
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session) {
        System.out.println("开启连接" + id);
        onlineSessionClientMap.put(id, session);
    }

    /**
     * 连接关闭回调
     *
     * @param id
     * @param session
     */
    @OnClose
    public void onClose(@PathParam("id") String id, Session session) {
        //从map集合中移除
        System.out.println("断开连接" + id);
        onlineSessionClientMap.remove(id);
    }

    /**
     * 收到消息后的回调
     *
     * @param message
     * @param session
     */
	@OnMessage
    public void onMessage(String message, Session session) {
        Message msg = JSONObject.parseObject(message, Message.class);
        if (msg != null && msg.getTo() != null) {
            Session fromSession = onlineSessionClientMap.get(msg.getFrom());
            if (fromSession != null) {
                // 前端会通过JSON.parse解析message
                fromSession.getAsyncRemote().sendText(message);
            }
            Session toSession = onlineSessionClientMap.get(msg.getTo());
            if (toSession != null) {
                toSession.getAsyncRemote().sendText(message);
            }
        }
    }

    /**
     * 发生错误时的回调
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
    }

}

以上的消息实体Message如下

创建Message.java,利用lombok快速生成构造方法,以及get,set方法。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {

    // 发送方
    private String from;

    // 接收方
    private String to;

    // 消息内容
    private String content;
}

现在已经完成了基础内容的接收发送,需要将WebSocketServer装配到Spring当中。

新建WebConfig.java

@Configuration
public class WebConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        ServerEndpointExporter exporter = new ServerEndpointExporter();
        exporter.setAnnotatedEndpointClasses(WebSocketServer.class);
        return exporter;
    }
}

完工~接下来看前端部分

我的vue3项目已经装好antdesign-for-vue

看代码

<script setup>
const route = useRoute()

// route.params.id 获取路由上的参数
const es = new WebSocket('ws://localhost:8080/test/' + route.params.id)
es.onopen = function (e) {
  console.log('连接成功', e);
}
es.onerror = function (e) {
  console.log('连接失败', e);
}
es.onclose = function (e) {
  console.log('连接关闭', e);
}
es.onmessage = function (e) {
  msgList.value.push(JSON.parse(e.data))
}

const inputValue = ref('')
const toValue = ref('')

const send = () => {
  // 后端定义的Message消息体是这样子的
  es.send(JSON.stringify({
    from: route.params.id,
    to: toValue.value,
    content: inputValue.value
  }))
  inputValue.value = ''
}

const close = () => {
  es.close()
}

const msgList = ref([])

</script>

<template>
  <div class="h-64">
    <p>收到消息:</p>
    <p v-for="msg in msgList">{{ msg.from }}说:{{ msg.content }}</p>
  </div>
  <a-space>
    <a-input v-model:value="inputValue" @keydown.enter="send"></a-input>
    <a-input class="w-10" v-model:value="toValue"></a-input>
    <a-button type="primary" @click="send">发送</a-button>
    <a-button type="primary" @click="close">关闭</a-button>
  </a-space>
</template>

启动项目,打开http://localhost:5173/#/test/1

路由自己配置,主要为了获取路由上的参数,界面如下
在这里插入图片描述

再打开一个页面http://localhost:5173/#/test/2

假设参数为1的要给参数为2的发送实时消息,输入发送内容,发送目标填2

发送之后1和2会看到如下

在这里插入图片描述

切换到2,也发送消息
在这里插入图片描述

到此,最简易版本的双向通讯搭建完成。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你熬夜了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值