apisix转发websocket
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",
"pass_host": "pass"
},
"enable_websocket": true,
"status": 1
}