Nginx+Jetty+SpringMvc配置WebSocket

2017-07-21  本文已影响241人  Shauway

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

支持 wswss 协议

软件版本

软件 版本
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配置

  1. 拷贝 JETTY_HOME/modules/websocket.modJETTY_BASE/modules/websocket.mod
  2. 创建 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>

参考

  1. Websocket协议的学习、调研和实现
  2. Nginx WebSocket Proxying
上一篇 下一篇

猜你喜欢

热点阅读