WebSocket背景
Websocket是html5提出的一个协议规范,参考rfc6455。
websocket约定了一个通信的规范,通过一个握手的机制,客户端(浏览器)和服务器(webserver)
之间能建立一个类似tcp的连接,从而方便c-s之间的通信。在websocket出现之前,web交互一般是
基于http协议的短连接或者长连接。
WebSocket是为解决客户端与服务端实时通信而产生的技术。websocket协议本质上是一个基于tcp
的协议,是先通过HTTP/HTTPS协议发起一条特殊的http请求进行握手后创建一个用于交换数据的TCP
连接,此后服务端与客户端通过此TCP连接进行实时通信。
WebSocket协议
框架图
jetty
nginx --> jetty
jetty
支持 ws
和 wss
协议
软件版本
软件 | 版本 |
---|---|
Nginx | 1.10.3 |
Jetty | 9.3.16.v20170120 |
Spring | 4.3.6.RELEASE |
Nginx配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream backend {
sticky;
server localhost:6565;
server localhost:6666;
}
server {
listen 0.0.0.0:80;
server_name foo.bar.com;
server_tokens off;
location /services/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
include proxy.conf;
}
error_page 497 https://$host$uri?$args;
}
server {
listen 0.0.0.0:443 ssl http2;
server_name foo.bar.com;
server_tokens off;
ssl on;
ssl_certificate ssl/foo.bar.com.crt;
ssl_certificate_key ssl/foo.bar.com.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_verify_client off;
location /services/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
include proxy.conf;
}
error_page 497 https://$host$uri?$args;
}
重点就三行
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
Jetty配置
- 拷贝
JETTY_HOME/modules/websocket.mod
至JETTY_BASE/modules/websocket.mod
- 创建
JETTY_HOME/start.d/websocket.ini
内容如下
--module=websocket
SpringMvc配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd">
<!-- websocket -->
<websocket:handlers>
<websocket:mapping path="/echo" handler="echoWebsocketHandler"/>
<websocket:handshake-handler ref="handshakeHandler"/>
</websocket:handlers>
<bean id="handshakeHandler" class="org.springframework.web.socket.server.support.DefaultHandshakeHandler">
<constructor-arg ref="upgradeStrategy"/>
</bean>
<bean id="upgradeStrategy" class="org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy">
<constructor-arg ref="serverFactory"/>
</bean>
<bean id="serverFactory" class="org.eclipse.jetty.websocket.server.WebSocketServerFactory">
<constructor-arg ref="servletContext" type="javax.servlet.ServletContext"/>
<constructor-arg ref="webSocketPolicy" type="org.eclipse.jetty.websocket.api.WebSocketPolicy"/>
</bean>
<bean id="webSocketPolicy" class="org.eclipse.jetty.websocket.api.WebSocketPolicy">
<constructor-arg value="SERVER"/>
<property name="inputBufferSize" value="8092"/>
<property name="idleTimeout" value="600000"/>
</bean>
</beans>