SockJS完成实时拉拉扯扯

基于tomcat运行HTML5 WebSocket echo例子

一:概述

作为HTML5新特色之大器晚成的WebSocket组件,在实时性有确定必要的WEB应用开荒中照旧有早晚发挥特长,高版本的IE、Chrome、FF浏览器都辅助Websocket,标准的Websocket通信是依照EscortFC6455达成劳务器端与客商端握手与音信接发的。要是对Websocket通讯不是太掌握,能够查阅LacrosseFC文书档案就可以,简单说就是由此发送HTTP乞请,完毕双方握手,将无状态的HTTP通讯左券进一层进级成有情况的通信左券,同不经常候Websocket还协助子协议选项与安全传输。标准的websocket连接U奇骏L以ws开端,若是是基于TLS的则以wss发轫。基于Websocket能够很便利的付出基于web闲聊程序,各样网页消息通告与推送布告。

举例非要扒意气风发扒websocket的现世前世来讲,还记得最初的依照HTTP轮询实现网页即时通讯的法子,这种做法比较消耗电源、于是有人改善了编制程序CometD长连接方式,但是本质上大概万变不离其宗,而websocket的现身正巧解决了这个标题,但是不菲浏览器的低版本依旧不帮助websocket,于是还催生了生机勃勃部分依照websocket思想贯彻的JS通讯框架,在那之中学得相比像的有SockJS与socket.io,他们都称为协理websocket,然后若是浏览器端不扶助原生的websocket,它们会自行启用fallback选项使用其余诸如ajax、Http轮询、长轮询/连接、以致是flash的socket等体制达成模拟websocket的做事格局,可是他们最大的害处是只要顾客端应用了这几个框架,服务器必得用它们,不然等待开垦者正是第一次全国代表大会堆不能够则避的标题,同期广大都以无解的。首要缘由在于它们达成团结的公约集,不照它们的格式管理数量无法玩。聊天说的略微多。

二 : 完成步骤

汤姆cat7的高版本中落成了websocket服务器端本田UR-VFC6455典型公约,可以跟浏览器端websocket进行通讯,首先要坚实如下几步:

 

  1. 设置高版本JDK – JDK8

  2. 安装tomcat 7.0.64

  3. 在eclipse中创设二个动态的web项目

 

传闻JS普拉多规范,Java中落实websocket的规范接口能够依赖注明方式,tomcat也做好了,唯有大家贯彻如下代码,就可以成立三个websocket回声服务器:

 

package com.websocket.demo;

import java.io.IOException;
import java.nio.ByteBuffer;

import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = /echo)
public class EchoExample {

 @OnMessage
 public void echoTextMessage(Session session, String msg, boolean last) {
  try {
   if (session.isOpen()) {
    System.out.println(received from client message =  + msg);
    session.getBasicRemote().sendText(msg, last);
   }
  } catch (IOException e) {
   try {
    session.close();
   } catch (IOException e1) {
   }
  }
 }

 @OnOpen
    public void openConn(Session session) throws IOException {
     session.getBasicRemote().sendText(hello web socket); // means open it
    }

    @OnMessage
    public void echoBinaryMessage(Session session, ByteBuffer bb, boolean last) {
     System.out.println(send binary message...);
        try {
            if (session.isOpen()) {
             System.out.println(byte buffer lenghth :  + bb.array().length);
             System.out.println(byte buffer content:  + ((bb.array()[0]) & 0xff));
             System.out.println(byte buffer content:  + ((bb.array()[1]) & 0xff));
             System.out.println(byte buffer content:  + ((bb.array()[2]) & 0xff));
                session.getBasicRemote().sendBinary(bb, last);
            }
        } catch (IOException e) {
            try {
                session.close();
            } catch (IOException e1) {
                // Ignore
            }
        }
    }

}

 

什么样在tomcat中运维websocket服务器,首先必要在web.xml增多如下配置:

 

  org.apache.tomcat.websocket.server.WsContextListener

下一场实现ServerApplicationConfig接口,达成如下:

 

 

/*
 *
 */
package com.config.websocket.client;

import java.util.HashSet;
import java.util.Set;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;

public class ScanWebSocketSeverConfig implements ServerApplicationConfig {

 @Override
 public Set getEndpointConfigs(Set result = new HashSet();
/*  if (scanned.contains(EchoWsChatSever.class)) {
   result.add(ServerEndpointConfig.Builder.create(EchoWsChatSever.class, /echo).build());
  }*/
  return result;
 }

 @Override
 public Set clazz : scanned) {
   if (clazz.getPackage().getName().startsWith(com.websocket.)) {
    System.out.println(find end point :  + clazz.getName());
    results.add(clazz);
   }
  }
  return results;
 }
}

创设网页echo.html,内容如下:

 

 

<script> var ws = null; var count = 0; function
setConnected(connected) { document.getElementById(‘connect’).disabled =
connected; document.getElementById(‘disconnect’).disabled = !connected;
document.getElementById(‘echo’).disabled = !connected; } function
connect() { var target = document.getElementById(‘target’).value; if
(target == ”) { alert(‘Please select server side connection
implementation.’); return; } if (‘WebSocket’ in window) { ws = new
WebSocket(target); } else if (‘MozWebSocket’ in window) { ws = new
MozWebSocket(target); } else { alert(‘WebSocket is not supported by this
browser.’); return; } ws.onopen = function () { setConnected(true);
log(‘Info: WebSocket connection opened.’); }; ws.onmessage = function
(event) { log(‘Received: ‘ + event.data); if(event.data instanceof
ArrayBuffer) { var bytes = new Uint8Array(event.data);
alert(bytes.length + : + bytes[0]); } }; ws.onclose = function (event)
{ setConnected(false); log(‘Info: WebSocket connection closed, Code: ‘ +
event.code + (event.reason == ? : , Reason: + event.reason)); }; }
function disconnect() { if (ws != null) { ws.doClose(); ws = null; }
setConnected(false); } function echo() { if (ws != null) { var message =
document.getElementById(‘message’).value; log(‘Sent: ‘ + message);
ws.send(JSON.stringify({‘textMessage’: message})); count++ } else {
alert(‘WebSocket connection not established, please connect.’); } }
function log(message) { var echomsg =
document.getElementById(‘echomsg’); var p = document.createElement(‘p’);
p.style.wordWrap = ‘break-word’;
p.appendChild(document.createTextNode(message)); echomsg.appendChild(p);
while (echomsg.childNodes.length > 25) {
echomsg.removeChild(console.firstChild); } echomsg.scrollTop =
console.scrollHeight; } document.addEventListener(DOMContentLoaded,
function() { // Remove elements with noscript class –

is not allowed in XHTML var noscripts =
document.getElementsByClassName(noscript); for (var i = 0; i <
noscripts.length; i++) {
noscripts[i].parentNode.removeChild(noscripts[i]); } }, false);
</script>

设计初志是通过websocket完成网页实时报道闲谈。

URL – ws://localhost:8080/websocket/echo

Connect

Disconnect

Here is a message!

Echo message

 

三 :运营与测验

 

卷入陈设到tomcat之后,运营chrom浏览器,输入地方:

永利集团304com 1

新生,作者还开采,tomcat完成websocket服务器端居然不协助子协议

永利集团304com,跟3W上的测量试验U普拉多L结果不均等。

 

WebSocket echo例子 后生可畏:概述
作为HTML5新天性之大器晚成的WebSocket组件,在实时性有早晚要求的WEB应用开拓中依然有自然发挥专长,…

工程情形:apache-tomcat-7.0.68+jdk1.7+maven+eclipse

设计思路:客商端登陆网页构建socket连接,后台记录客户连接消息并做标志;当客商在网页端发送闲聊音讯至后台,后台选用音讯后将音信发送至选拔者,同期后端对信息举行一心一德保存。

简言之代码完毕demo如下:

1、pom.xml首要配置

        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>


        <!-- AspectJ -->
        <!-- <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency> -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

 2、websocket服务端完成

package com.milanosoft.RCS.web.webSocket.config;

import com.milanosoft.RCS.web.webSocket.hndler.SystemWebSocketHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import com.milanosoft.RCS.web.webSocket.interceptor.HandshakeInterceptor;
import org.springframework.context.annotation.Bean;

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
        WebSocketConfigurer {

    public WebSocketConfig() {
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(systemWebSocketHandler(), "/websck").addInterceptors(new HandshakeInterceptor());

        System.out.println("registed!");
        registry.addHandler(systemWebSocketHandler(), "/sockjs/websck").addInterceptors(new HandshakeInterceptor())
                .withSockJS();

    }

    @Bean
    public WebSocketHandler systemWebSocketHandler() {
        //return new InfoSocketEndPoint();
        return new SystemWebSocketHandler();
    }

}

 3、websocket连接内外的事件类

package com.milanosoft.RCS.web.webSocket.interceptor;

import java.util.Map;

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


@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {

        //解决The extension [x-webkit-deflate-frame] is not supported问题
        if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
            request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
        }

        System.out.println("Before Handshake");
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception ex) {
        System.out.println("After Handshake");
        super.afterHandshake(request, response, wsHandler, ex);
    }

}

//解决The extension [x-webkit-deflate-frame] is not supported问题
        if(request.getHeaders().containsKey(“Sec-WebSocket-Extensions”))
{
            request.getHeaders().set(“Sec-WebSocket-Extensions”,
“permessage-deflate”);
        }

其间标深绿的代码是为了消亡上面的谬误,大概是ios手提式有线电话机safari浏览器版本难点引起的。

org.springframework.web.socket.server.HandshakeFailureException:
Uncaught failure for request ;
nested exception is java.lang.IllegalArgumentException: The extension
[x-webkit-deflate-frame] is not supported

 4、websocket消息管理类

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.milanosoft.RCS.web.webSocket.hndler;

import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

/**
 *
 * @author lzk
 */
@Component
public class SystemWebSocketHandler implements WebSocketHandler {

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("connect to the websocket success......");
        session.sendMessage(new TextMessage("Server:connected OK!"));
    }

    @Override
    public void handleMessage(WebSocketSession wss, WebSocketMessage<?> wsm) throws Exception {
        TextMessage returnMessage = new TextMessage(wsm.getPayload()
                + " received at server");
        System.out.println(wss.getHandshakeHeaders().getFirst("Cookie"));
        wss.sendMessage(returnMessage);
    }

    @Override
    public void handleTransportError(WebSocketSession wss, Throwable thrwbl) throws Exception {
        if(wss.isOpen()){
            wss.close();
        }
       System.out.println("websocket connection closed......");
    }

    @Override
    public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {
        System.out.println("websocket connection closed......");
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

}

 5、客户端页面

<%@ page language=”java” contentType=”text/html; charset=UTF-8″  

    pageEncoding=”UTF-8″%>  

<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “;  

<html>  

<head>  

<%session.setAttribute(“user”, “lzk”); %>  

<title>WebSocket/SockJS Echo Sample (Adapted from Tomcat’s echo sample)</title>  

    <style type=”text/css”>  

        #connect-container {  

            float: left;  

            width: 400px  

        }  

        #connect-container div {  

            padding: 5px;  

        }  

        #console-container {  

            float: left;  

            margin-left: 15px;  

            width: 400px;  

        }  

        #console {  

            border: 1px solid #CCCCCC;  

            border-right-color: #999999;  

            border-bottom-color: #999999;  

            height: 170px;  

            overflow-y: scroll;  

            padding: 5px;  

            width: 100%;  

        }  

        #console p {  

            padding: 0;  

            margin: 0;  

        }  

    </style>  

    <script src=”;  

    <script type=”text/javascript”>  

        var ws = null;  

        var url = null;  

        var transports = [];  

        function setConnected(connected) {  

            document.getElementById(‘connect’).disabled = connected;  

            document.getElementById(‘disconnect’).disabled = !connected;  

            document.getElementById(‘echo’).disabled = !connected;  

        }  

        function connect() {  

            //alert(url);  

            //console.log(url);  

            if (!url) {  

                alert(‘Select whether to use W3C WebSocket or SockJS’);  

                return;  

            }  

            //ws = (url.indexOf(‘sockjs’) != -1) ?new SockJS(url, undefined, {protocols_whitelist: transports}) : new WebSocket(url);  

            if (‘WebSocket’ in window) {  

                ws= new WebSocket(“ws://192.168.1.104:8080/SpringWebSocketPush/websck”);  

                console.log(“ws://192.168.1.104:8080/SpringWebSocketPush/websck”);  

            }else {  

                ws = new SockJS(“”);  

                console.log(“”);  

            }  

            //websocket = new SockJS(“”);  

            ws.onopen = function () {  

                alert(‘open’);  

                setConnected(true);  

                //log(‘Info: connection opened.’);  

            };  

            ws.onmessage = function (event) {  

                alert(‘Received:’ + event.data);  

                log(‘Received: ‘ + event.data);  

            };  

            ws.onclose = function (event) {  

                setConnected(false);  

                log(‘Info: connection closed.’);  

                log(event);  

            };  

发表评论

电子邮件地址不会被公开。 必填项已用*标注