websocket

1.websocket

(1).jdk

jdk7开始自带javax.websocket包,也可以依赖

<dependency>
      <groupId>javax.websocket</groupId>
      <artifactId>javax.websocket-api</artifactId>
      <version>1.0</version>
      <scope>provided</scope>
    </dependency>

package com.csf.ws.test;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * Created by yunbing.hao on 2016/12/5.
 */
@ServerEndpoint("/websocketTest")
public class WebSocketTest {
    @OnMessage
    public void onMessage(String message, Session session) throws IOException, InterruptedException {
        System.out.println("................................." + message);
        session.getBasicRemote().sendText(message);
//        // Print the client message for testing purposes
//        System.out.println("Received: " + message);
//
//        // Send the first message to the client
//        session.getBasicRemote().sendText("This is the first server message");
//
//        // Send 3 messages to the client every 5 seconds
//        int sentMessages = 0;
//        while (sentMessages < 3) {
//            Thread.sleep(5000);
//            session.getBasicRemote().sendText("This is an intermediate server message. Count: " + sentMessages);
//            sentMessages++;
//        }
//
//        // Send a final message to the client
//        session.getBasicRemote().sendText("This is the last server message");
    }

    @OnOpen
    public void onOpen() {
        System.out.println("Client connected");
    }

    @OnClose
    public void onClose() {
        System.out.println("Connection closed");
    }

    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }
}

(2).spring websocket

<!-- websocket -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-websocket</artifactId>
      <version>8.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
      <version>8.0.23</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.5.3</version>
      <scope>runtime</scope>
    </dependency>

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${springframework.version}</version>
    </dependency>

完整依赖:

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <springframework.version>4.2.6.RELEASE</springframework.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${springframework.version}</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
      <groupId>javax.websocket</groupId>
      <artifactId>javax.websocket-api</artifactId>
      <version>1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <!-- spring -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${springframework.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jms</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!-- websocket -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-websocket</artifactId>
      <version>8.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
      <version>8.0.23</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.5.3</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

配置springmvc:

web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <description>用来测试WebSocket基础上推送的功能</description>
    <distributable />
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext-*.xml
        </param-value>
    </context-param>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    
    
    <!-- Spring 刷新Introspector防止内存泄露 -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcher-servlet.xml</param-value>
        </init-param> -->
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>testSocket.jsp</welcome-file>
    </welcome-file-list>
</web-app>
WEB-INF/dispatcher-servlet.xml:
<?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:context="http://www.springframework.org/schema/context"
       xmlns:jbbc="http://www.springframework.org/schema/jdbc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd  
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd       
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

</beans>
websocket拦截器:
import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {
        System.out.println("..........................................beforeHandshake");
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }
    
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception ex) {
        System.out.println(".............................................afterHandshake");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
webSocketHandler:
import org.springframework.web.socket.*;

public class SystemWebSocketHandler implements WebSocketHandler{

    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println(".............................afterConnectionEstablished");
        
    }

    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        System.out.println("..........................."+message.getPayload());
        session.sendMessage(message);
        
    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println(exception);
        System.out.println("...........................handleTransportError");
        
    }

    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        System.out.println("...........................afterConnectionClosed");
        
    }

    public boolean supportsPartialMessages() {
        System.out.println("...........................supportsPartialMessages");
        return false;
    }

}
spring配置:
<?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: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/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">
    <!-- <context:annotation-config/> 自动扫描的包名 <context:component-scan base-package="com.csf.ws"></context:component-scan>
        <tx:annotation-driven/> -->
    <!--<websocket:handlers allowed-origins="*">
        <websocket:mapping path="/websocket" handler="myHandler" />
        <websocket:handshake-interceptors>
            <bean class="com.csf.ws.HandshakeInterceptor" />
        </websocket:handshake-interceptors>
        <websocket:sockjs/>
    </websocket:handlers>
    <bean id="myHandler" class="com.csf.ws.SystemWebSocketHandler" />-->

     <websocket:handlers>
        <websocket:mapping path="/myHandler" handler="myHandler" />
        <websocket:handshake-interceptors>
            <bean class="com.csf.ws.HandshakeInterceptor" />
        </websocket:handshake-interceptors>
        <websocket:sockjs />
    </websocket:handlers>
    <bean id="myHandler" class="com.csf.ws.SystemWebSocketHandler" />


</beans>


(1).js自带websocket客户端
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
    <meta charset="utf-8">
    <title>Chat</title>
    <script language="javascript" type="text/javascript">
            
            var wsUri = "ws://192.168.137.254/ws/websocket";

            function init() {
                bt_open_socket=document.getElementById("open_socket");
                bt_close_socket=document.getElementById("close_socket");
                
                output = document.getElementById("output");

                bt_close_socket.disabled = true;
            }

            function open_socket(){
                websocket = new WebSocket(wsUri);
                websocket.onopen = function(evt) {
                    onOpen(evt)
                };
                websocket.onmessage = function(evt) {
                    onMessage(evt)
                };
                websocket.onerror = function(evt) {
                    onError(evt)
                };
                
                bt_close_socket.disabled = false;
                bt_open_socket.disabled = true;
                
                waitForSocketConnection(websocket, function() {
                    websocket.send("/set nickname "+document.getElementById("nickname").value);
                    //websocket.send("/set room "+ "0");
                    document.getElementById("textID").focus();
                });
                
                document.getElementById("nickname").style.visibility="hidden";
                
                
            }
            function close_socket(){
                websocket.close()
                
                bt_close_socket.disabled = true;
                bt_open_socket.disabled = false;
            }
            
            function send_message() {
                if(textID.value!="")
                    doSend(textID.value);
            }
            function onOpen(evt) {
                writeToScreen("Connected to Endpoint!");
            }
            function onMessage(evt) {
                writeToScreen(evt.data);
            }
            function onError(evt) {
                writeToScreen('ERROR: ' + evt.data);
            }
            function doSend(message) {
                websocket.send(message);
                document.getElementById("textID").value="";
            }
            function writeToScreen(message) {
                var pre = document.createElement("p");
                pre.style.wordWrap = "break-word";
                pre.innerHTML = message;
                 
                output.appendChild(pre);
                output.scrollTop = output.scrollHeight;   
            }
            
            function change_nickname() {  
                websocket.send("");
            }
            
            function waitForSocketConnection(socket, callback){
                setTimeout(
                    function(){
                        if (socket.readyState === 1) {
                            if(callback !== undefined){
                                callback();
                            }
                            return;
                        } else {
                            waitForSocketConnection(socket,callback);
                        }
                    }, 5);
            };
            
            window.addEventListener("load", init, false);
            
            window.onbeforeunload = function (evt) {
                alert("A");
                close_socket();
            };
        </script>
    <h1 style="text-align: center;">WebSocket Test</h1>
    <br>
    <div style="text-align: center;">

        <div>
            <input id="nickname" name="nickname" placeholder="Input your Nickname" type="text"
                onKeyPress="if (event.keyCode==13){change_nickname();event.returnValue=false}">    
            <br>
        </div>
        <input id="open_socket" onclick="open_socket()" value="Open WebSocket"
            type="button"> <input id="close_socket"
            onclick="close_socket()" value="Close WebSocket" type="button">
        <div>
            <input onclick="send_message()" value="Send" type="button"> <input
                id="textID" name="message" value="" type="text" placeholder=""
                onKeyPress="if (event.keyCode==13){ send_message();event.returnValue=false}"><br>
        </div>
    </div>
    <div id="output" style="max-height: 80%; overflow-y: scroll;"></div>
</body>
</html>
2.socketJs客户端:
需将spring配置文件中加上<websocket:sockjs/>标签
chat.jsp:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
    <meta charset="utf-8">
    <title>Chat</title>
    <script src="//cdn.jsdelivr.net/sockjs/1/sockjs.min.js"></script>
    <script language="javascript" type="text/javascript">
            var wsUri="http://192.168.137.254/ws/websocket";

            function init() {
                bt_open_socket=document.getElementById("open_socket");
                bt_close_socket=document.getElementById("close_socket");
                
                output = document.getElementById("output");

                bt_close_socket.disabled = true;
            }
            function open_socket(){
                websocket = new SockJS(wsUri);
                websocket.onopen = function(evt) {
                    onOpen(evt)
                };
                websocket.onmessage = function(evt) {
                    onMessage(evt)
                };
                websocket.onerror = function(evt) {
                    onError(evt)
                };
                
                bt_close_socket.disabled = false;
                bt_open_socket.disabled = true;
                
                waitForSocketConnection(websocket, function() {
                    websocket.send("/set nickname "+document.getElementById("nickname").value);
                    //websocket.send("/set room "+ "0");
                    document.getElementById("textID").focus();
                });
                
                document.getElementById("nickname").style.visibility="hidden";
                
                
            }
            function close_socket(){
                websocket.close()
                
                bt_close_socket.disabled = true;
                bt_open_socket.disabled = false;
            }
            
            function send_message() {
                if(textID.value!="")
                    doSend(textID.value);
            }
            function onOpen(evt) {
                writeToScreen("Connected to Endpoint!");
            }
            function onMessage(evt) {
                writeToScreen(evt.data);
            }
            function onError(evt) {
                writeToScreen('ERROR: ' + evt.data);
            }
            function doSend(message) {
                websocket.send(message);
                document.getElementById("textID").value="";
            }
            function writeToScreen(message) {
                var pre = document.createElement("p");
                pre.style.wordWrap = "break-word";
                pre.innerHTML = message;
                 
                output.appendChild(pre);
                output.scrollTop = output.scrollHeight;   
            }
            
            function change_nickname() {  
                websocket.send("");
            }
            
            function waitForSocketConnection(socket, callback){
                setTimeout(
                    function(){
                        if (socket.readyState === 1) {
                            if(callback !== undefined){
                                callback();
                            }
                            return;
                        } else {
                            waitForSocketConnection(socket,callback);
                        }
                    }, 5);
            };
            
            window.addEventListener("load", init, false);
            
            window.onbeforeunload = function (evt) {
                alert("A");
                close_socket();
            };
        </script>
    <h1 style="text-align: center;">WebSocket Test</h1>
    <br>
    <div style="text-align: center;">

        <div>
            <input id="nickname" name="nickname" placeholder="Input your Nickname" type="text"
                onKeyPress="if (event.keyCode==13){change_nickname();event.returnValue=false}">    
            <br>
        </div>
        <input id="open_socket" onclick="open_socket()" value="Open WebSocket"
            type="button"> <input id="close_socket"
            onclick="close_socket()" value="Close WebSocket" type="button">
        <div>
            <input onclick="send_message()" value="Send" type="button"> <input
                id="textID" name="message" value="" type="text" placeholder=""
                onKeyPress="if (event.keyCode==13){ send_message();event.returnValue=false}"><br>
        </div>
    </div>
    <div id="output" style="max-height: 80%; overflow-y: scroll;"></div>
</body>
</html>

3.nginx代理配置:
http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
   upstream test {
      server 192.168.137.254:8080;
   }
    server {
        listen       80;
        server_name  192.168.137.254;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://localhost:8080/;
            root   html;
            index  index.html index.htm;
        }
         location  ^~/ws/websocket {
                 proxy_pass http://test;
                 proxy_redirect    off;
                 proxy_set_header X-Real-IP $remote_addr;
                 proxy_set_header Host $host;
                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                 proxy_set_header X-NginX-Proxy true;

                 proxy_http_version 1.1;
                 proxy_set_header Upgrade $http_upgrade;
                 proxy_set_header Connection "upgrade";

                 proxy_connect_timeout   3;
                 proxy_send_timeout      30;
                 proxy_read_timeout      86400;
    }
proxy_read_timeout配置成一天,配置时间秒太小,会自动断开连接

 

 

posted @ 2016-12-06 15:26  Runny_Hao  阅读(185)  评论(0)    收藏  举报