目录
1、说明
apisix网关对接websocket,参数以及使用可以看官方文档
WebSocket Authentication | Apache APISIX® -- Cloud-Native API Gateway
注意事项:
(1)官方文档是websocket要加认证,但自测发现可以不加认证插件
(2)官方文档说要把upstream的shema设置为https(这是个坑),实际使用的时候发现websocket服务器是https就用https,否则还是要用http。 被这个卡了很久
2、配置例子
2.1、websocket测试类
(1)maven依赖
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
(2)配置类
@Slf4j
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
log.info("我被注入了");
return new ServerEndpointExporter();
}
}
(3)暴露给客户端的服务
@Slf4j
@Component
@ServerEndpoint("/socket/websocket/recive")
public class WebSocketService {
// 定义属性
private Session session;
//创建一个set用来存储用户
private static CopyOnWriteArraySet<WebSocketService> websockets = new CopyOnWriteArraySet<>();
/**
* 当有用户创建连接时候调用该方法
*/
@OnOpen
public void onOpen(Session session) {
// 给当前的Session赋值
this.session = session;
// 将当前对象添加到CopyOnWriteArraySet 中
websockets.add(this);
// 可以获取该session,但是其实也是一个内存地址
log.info("【建立连接】 用户为:" + this.session);
// 获取总数,这个不难理解,实际上这个集合的总数,就是WebSocket连接的总数
log.info("【建立连接】 总数为:" + websockets.size());
}
/**
* 有用户连接断开时候触发该方法
*/
@OnClose
public void onClose() {
websockets.remove(this); // 将当前的对象从集合中删除
log.info("【连接断开】 用户为:" + this.session);
log.info("【连接断开】 总数为:" + websockets.size());
}
/**
* 这个方法是客户端给服务端发送消息触发该方法
* @param message : 消息内容
*/
@OnMessage
public void onMessage(String message) {
log.info("来自客户端的消息:{}",message);
sendMessage(message+"收到回复");
}
/**
* 发送消息的方法,方便后期别的service调用
*
* @param message 消息内容
*/
public void sendMessage(String message) {
for (WebSocketService websocket : websockets) { // 遍历该Set集合
log.info("广播消息 【给用户】 :" + websocket + "发送消息" + "【" + message + "】"); // 获取一个,在控制台打印一句话
try {
websocket.session.getBasicRemote().sendText(message); // 发送消息的方法
} catch (IOException e) {
e.getMessage();
}
}
}
}
小插曲
用postman访问websocket一直连不通,会报错Error during WebSocket handshake: Unexpected response code: 200。 这个报错困扰了很久。
websocket被识别成了http接口。因此在登录过滤器,需要蔽这个接口,nacos的配置增加sso.excluded.paths=/**/websocket/**
如果用的别的安全登录插件,也要相应的做接口屏蔽
2.2、配置apisix的websocket路由
下面是自己写的一个websocket例子,发布服务是http, 配置成路由route如下,可以正常转发访问。需要配置上游节点,路由转发
{
"uri": "/websoket/msg",
"name": "测试websocket1218",
"desc": "测试websocket1218",
"methods": [
"GET"
],
"plugins": {
"proxy-rewrite": {
"pluginName": "proxy-rewrite",
"uri": "/dgcode/socket/websocket/recive",
"use_real_request_uri_unsafe": false
}
},
"upstream": {
"nodes": [
{
"host": "10.255.158.74",
"port": 9599,
"weight": 1
}
],
"type": "roundrobin",
"hash_on": "vars",
"scheme": "http",
"pass_host": "pass"
},
"enable_websocket": true,
"status": 1
}