Nginx整合Spring cloud gateway转发webSocket请求
Nginx整合Spring cloud gateway转发webSocket请求
前言
在整合过程中,很容易就犯下一下错误,导致转发webSocket请求的时候,老是出现一些小问题。
记录一下
思路
1、nginx配置支持webSocket转发
2、Spring cloud gateway转发webSocket请求
3、webSocket服务器接收并处理webSocket请求
配置nginx
在http模块内,配置3块内容
- 支持协议升级
- 网关服务路由
- location识别转发
我这里转发到2个gateway服务,配置了一下upstream
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream gateway{
server 192.168.55.8:8080;
server 192.168.55.9:8080;
}
location /ws/{
proxy_pass http://gateway/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 60s;
proxy_read_timeout 7200s;
proxy_send_timeout 60s;
}
配置Spring cloud gateway
# Websocket路由
- id: websocket_route
uri: lb:ws://test-service
predicates:
- Path=/websocket/**
test-service 是webSocket请求最终处理的服务,test-service是服务名。
根据1级路径是websocket的请求进行转发
配置webSocket服务(test-service)
1、tomcat方式实现
2、spring封装实现
3、netty方式实现
此处简单介绍使用方式2, 配置,握手拦截,请求端点处理。
@Configuration
@EnableWebSocket
public class WebsocketSpringConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebsocketSpringController(),"/websocket/user").addInterceptors(new WebsocketInterceptor()).setAllowedOrigins("*");
}
}
public class WebsocketInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
map.put("token","");
return true;
}
@Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
}
}
public class WebsocketSpringController extends TextWebSocketHandler {
private final String charset = "UTF-8";
private WebSocketSession session;
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
this.session = session;
System.out.println(session);
session.sendMessage(new TextMessage("connected..."));
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
System.out.println(payload);
session.sendMessage(new TextMessage("received:" + payload));
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
super.handleTransportError(session, exception);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
super.afterConnectionClosed(session, status);
}
}
问题
遇到一些小问题
1、nginx配置问题
upstream 问题
一开始配置的是 upstream test_gateway ,后面改成 upstream gateway
upstream name的不能有特殊字符,各种结合等
2、服务网络问题
test-service 的ip地址不可达,注册中心显示的test-service的ip地址是一个内网地址,gateway无法访问到,gateway转发请求失败。
Invalid handshake response getStatus: 404
将test-service的ip地址修改,重新进行服务注册后一切正常。
3、webSocket服务配置错误
一开始配置的时候开启了SockJS
registry.addHandler(new WebsocketSpringController(),“/websocket/user”).addInterceptors(new WebsocketInterceptor()).setAllowedOrigins(“*”).withSockJS();
导致ws请求无法接收处理。
开启SockJS所处理的URL是“http://”或“https://”模式,而不是“ws://”和“wss://”
withSockJS配置去掉。
遇到的报错信息如下
报错信息1
An exception has been observed post termination, use DEBUG level to see the full stack: io.netty.handler.codec.http.websocketx.WebSocketClientHandshakeException: Connection prematurely closed BEFORE opening handshake is complete.
报错信息2
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value “*” since that cannot be set on the “Access-Control-Allow-Origin” response header. To allow credentials to a set of origins, list them explicitly or consider using “allowedOriginPatterns” instead.
报错信息3
“Invalid SockJS path ‘/123’ - required to have 3 path segments”
如果一开始没有用nginx做转发测试。
存在跟我一样的情况
不加nginx的时候转发ws是正常。加上nginx配置之后,就无法转发了,关键的是gateway不转发也不报错,nginx请求日志一切正常
不要怀疑,就是nginx配错了。请参考我的这套配置
更多推荐
所有评论(0)