需要实现前端页面->zuul网关->消息服务,建立websocket连接
使用spring-cloud-netflix-zuul-websocket 实现zuul网关层对websocket的转发;
注意事项:
1.前端使用sockjs,注意地址前缀
// 不要使用ws前缀!!,如果使用websocket(url),为ws前缀
var socket = new SockJS('http://datamgt-services.respool.wmcloud-qa.com/notify-websocket')
注:如果使用ws前缀会报如下异常:
sockjs.min.js:27 Failed to load ws://xx/info: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
2.后端注意开启跨域和指定sockjs协议:
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
//注册一个名字为"notify-websocket" 的endpoint,并指定 SockJS协议。 点对点-用
stompEndpointRegistry
.addEndpoint("/notify-websocket")
.setAllowedOrigins("*")
.withSockJS();
}
3.zuul层配置:
zuul:
routes:
service-notify:
path: /service-notify/**
service-id: service-notify
url: http://xxxx
customSensitiveHeaders: true
ws:
brokerages:
service-notify:
end-points: /notify-websocket
brokers: /topic
destination-prefixes: /send
注意:
- 前端访问时不要再加服务名称:
正确: new SockJS('http://zuul地址/notify-websocket')
错误: new SockJS('http://zuul地址/服务名称/notify-websocket') 会报404
- 配置文件必须指定zuul.routes.服务名称.url,否则报错
- 如果要动态指定服务的实际url怎么办,重写获取url的方法
/**
* 重写获取服务url的方法:原有方法读取配置的路由url,改为通过服务读取
* @param zuulProperties
* @return
*/
@Bean
public ZuulPropertiesResolver zuulPropertiesResolver(
final ZuulProperties zuulProperties) {
return new ZuulPropertiesResolver() {
@Override
public String getRouteHost(ZuulWebSocketProperties.WsBrokerage wsBrokerage) {
// 默认方法去读配置文件url属性
//return zuulProperties.getRoutes().get(wsBrokerage.getId()).getUrl();
//自己改写,可以通过注册中心读取服务地址、或者数据库等方式
return "http://xxx";
}
};
}
参考:
- https://spring.io/guides/gs/messaging-stomp-websocket/
- https://github.com/mthizo247/zuul-websocket-support-demo/blob/master/hello/src/main/java/com/github/mthizo247/hello/HelloApplication.java