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>