
websocket
WebSocket配置中会遇到的一些问题
分享 • jonychen1 发表了文章 • 0 个评论 • 1692 次浏览 • 2018-07-16 18:25
今天来整理一些我在工作中配置上遇到的一些问题。
Q1使用nginx代理后不能访问。报错WARNING:tornado.access:400 GET /ws (127.0.0.1) 0.79ms 或者连接失败后会反复发起连接请求。
需要在nginx的location中新增如下配置[code]# websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";[/code]
Q2 跨域问题(spring websocket)
经查阅官方文档springwebsocket 4.1.5版本前默认支持跨域访问,之后的版本默认不支持跨域,需要设置[code].setAllowedOrigins(“”)
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myWebSocketHandler(), "/echo.do").setAllowedOrigins("").addInterceptors(new HandshakeInterceptor());
registry.addHandler(myWebSocketHandler(), "/echo").setAllowedOrigins("").addInterceptors(new HandshakeInterceptor())
.withSockJS();
}[/code]
Q3 .do配置导致sockjs失效问题(spring websocket)
web.xml中添加如下配置[code]<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/sockjs/</url-pattern>
</servlet-mapping>[/code]websocket配置类中路径中不加sockjs[code]registry.addHandler(myWebSocketHandler(), "/echo").setAllowedOrigins("").addInterceptors(new HandshakeInterceptor())
.withSockJS();[/code]前端调用时应加上sockjs[code]websocket = new SockJS("http://127.0.0.1:8080/WebSocketTest001/sockjs/echo");[/code]
Q4 一个websocketsession对应多个session的情况
这是由于尽管每次都能保证有一个websocketsession存在,但客户端没连接一次tomcat都建立一个链接,除非你在请求头里添加cookie:JSESSIONID=xxxxxx
Q5 能收到客户端消息,后台也显示发送,但是客户端收不到
这个问题经我个人观察和猜测,应该是websocketsession没有成功关闭或者成功关闭但是和一个websocketsession对应多个session有关,因为我把上面的问题解决了之后,这个问题也没出现过了。
Two connections have the same unique ID? How do I identify them?
提问 • t182848232 回复了问题 • 3 人关注 • 2017-01-30 12:04
基于 Workerman 的简单聊天室
分享 • pader 发表了文章 • 0 个评论 • 1449 次浏览 • 2016-08-26 14:33
DEMO://do[dot]vgot[dot]net:2345/xchat
现在就一个聊天房间,有各种进入离开提醒,有在线人列表功能。
服务端目前就一个 websocket 服务进程,未来再用 GatewayWorker。
服务端代码很少://github[dot]com/xpader/Navigation/tree/master/Applications/XChat
主要是 JS://github[dot]com/xpader/Navigation/blob/master/static/xchat.js
代码不多,做着玩玩实现个小思路,供大家参考。
为什么不能发链接啊,真是醉了。
所以服务端发送数据的时候需要根据传输的数据类型设置这个标记位,在Workerman中如果是普... 显示全部 »
所以服务端发送数据的时候需要根据传输的数据类型设置这个标记位,在Workerman中如果是普通utf8文本,则需要设置
use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_BLOB;
如果是二进制数据,则需要设置
use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;
注意:如果没设置$connection->websocketType,则默认$connection->websocketType为BINARY_TYPE_BLOB(也就是utf8文本类型)。一般应用传输的都是utf8文本,例如传输的是json数据,所以不用手动设置$connection->websocketType。只有在传输二进制数据时(例如图片数据、protobuffer数据等)才要设置此属性为BINARY_TYPE_ARRAYBUFFER。
http://doc3.workerman.net/appendices/about-websocket.html
打开start_gateway.php 都有这段代码,默认是注释的,打开即可。
```php
// 当客户端连接上来时,设置连接的o... 显示全部 »
http://doc3.workerman.net/appendices/about-websocket.html
打开start_gateway.php 都有这段代码,默认是注释的,打开即可。
```php
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function($connection)
{
$connection->onWebSocketConnect = function($connection , $http_header)
{
// 可以在这里判断连接来源是否合法,不合法就关掉连接
// $_SERVER标识来自哪个站点的页面发起的websocket链接
if($_SERVER != 'http://chat.workerman.net')
{
$connection->close();
}
// onWebSocketConnect 里面$_GET $_SERVER是可用的
// var_dump($_GET, $_SERVER);
};
};
```
这里的原理类似如果你要和英国人交流,那么要使用英语。如果要和日本人交流,那么要使用日语。这里的语言就类似通讯协议,双方(客户端和服务端)必须使用相同的语言才能交流,否则无法通讯。
通讯协议不一致导致的常见的报错有:
> WebSocket connection to 'ws://xxx.com:xx/' failed: Error during WebSocket handshake: Unexpected response code: xxx
> WebSocket connection to 'ws://xxx.com:xx/' failed: Error during WebSocket handshake: net::ERR_INVALID_HTTP_RESPONSE
解决办法: 从上面两条报错看出,客户端使用的是ws连接是websocket协议。服务端也需要是
websocket协议才行,服务端监听部分代码需要指定websocket协议才能通讯,例如下面这样
如果是gatewayWorker,监听部分代码类似
> // websocket协议,这样客户端才能用ws://...来连。xxxx为端口不用改动
> $gateway = new Gateway('websocket://0.0.0.0:xxxx');
如果是Workerman则是
> // websocket协议,这样客户端才能用ws://...来连。xxxx为端口不用改动
> $worker = new Worker('websocket://0.0.0.0:xxxx');
Two connections have the same unique ID? How do I identify them?
回复提问 • t182848232 回复了问题 • 3 人关注 • 2017-01-30 12:04
WebSocket配置中会遇到的一些问题
分享 • jonychen1 发表了文章 • 0 个评论 • 1692 次浏览 • 2018-07-16 18:25
今天来整理一些我在工作中配置上遇到的一些问题。
Q1使用nginx代理后不能访问。报错WARNING:tornado.access:400 GET /ws (127.0.0.1) 0.79ms 或者连接失败后会反复发起连接请求。
需要在nginx的location中新增如下配置[code]# websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";[/code]
Q2 跨域问题(spring websocket)
经查阅官方文档springwebsocket 4.1.5版本前默认支持跨域访问,之后的版本默认不支持跨域,需要设置[code].setAllowedOrigins(“”)
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myWebSocketHandler(), "/echo.do").setAllowedOrigins("").addInterceptors(new HandshakeInterceptor());
registry.addHandler(myWebSocketHandler(), "/echo").setAllowedOrigins("").addInterceptors(new HandshakeInterceptor())
.withSockJS();
}[/code]
Q3 .do配置导致sockjs失效问题(spring websocket)
web.xml中添加如下配置[code]<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/sockjs/</url-pattern>
</servlet-mapping>[/code]websocket配置类中路径中不加sockjs[code]registry.addHandler(myWebSocketHandler(), "/echo").setAllowedOrigins("").addInterceptors(new HandshakeInterceptor())
.withSockJS();[/code]前端调用时应加上sockjs[code]websocket = new SockJS("http://127.0.0.1:8080/WebSocketTest001/sockjs/echo");[/code]
Q4 一个websocketsession对应多个session的情况
这是由于尽管每次都能保证有一个websocketsession存在,但客户端没连接一次tomcat都建立一个链接,除非你在请求头里添加cookie:JSESSIONID=xxxxxx
Q5 能收到客户端消息,后台也显示发送,但是客户端收不到
这个问题经我个人观察和猜测,应该是websocketsession没有成功关闭或者成功关闭但是和一个websocketsession对应多个session有关,因为我把上面的问题解决了之后,这个问题也没出现过了。
基于 Workerman 的简单聊天室
分享 • pader 发表了文章 • 0 个评论 • 1449 次浏览 • 2016-08-26 14:33
DEMO://do[dot]vgot[dot]net:2345/xchat
现在就一个聊天房间,有各种进入离开提醒,有在线人列表功能。
服务端目前就一个 websocket 服务进程,未来再用 GatewayWorker。
服务端代码很少://github[dot]com/xpader/Navigation/tree/master/Applications/XChat
主要是 JS://github[dot]com/xpader/Navigation/blob/master/static/xchat.js
代码不多,做着玩玩实现个小思路,供大家参考。
为什么不能发链接啊,真是醉了。