频道栏目
首页 > 程序开发 > 移动开发 > 其他 > 正文
SSM+websocket+二进制数据传输+sharedWorker
2017-09-11 09:33:22      个评论    来源:苏暖午后  
收藏   我要投稿

SSM+websocket+二进制数据传输+sharedWorker。

注意事项: 1.如果出现握手失败,检查路径之外还可以去查看拦截器是否做了什么处理。

WebSocket和sharedWork简介

WebSocket是持久化连接,用于解决浏览器与后台服务器双向通讯的问题
sharedWorker共享工作线程允许多个页面共享使用,每个页面都是链接到该共享工作线程的某个端口号上。页面通过该端口与共享工作线程进行通信

配置所需jar包


    org.springframework
    spring-messaging
    ${spring.framework.version}


    org.springframework
    spring-websocket
    ${spring.framework.version}

这里所用的版本最好和项目中所用到的spring其他内容统一,避免出现版本不兼容问题。
对版本的要求是:spring版本为 4.0 版本及以上, Tomcat 7.047 以上版本。

websocket入口

/**
 * Component注解告诉SpringMVC该类是一个SpringIOC容器下管理的类
 * 其实@Controller, @Service, @Repository是@Component的细化
 * @Configuration注解该类,等价于XML中配置beans标签
 */
@Configuration
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //一般浏览器都会支持
        registry.addHandler(WebSocketPushHandler(),"/webSocketServer").addInterceptors(new MyHandShakeInterceptor());
        //低版本浏览器使用此路径,等下页面上会讲到
        registry.addHandler(WebSocketPushHandler(), "/sockjs/webSocketServer").addInterceptors(new MyHandShakeInterceptor())
                .withSockJS();
    }
    @Bean
    public WebSocketHandler WebSocketPushHandler(){
        return new MyWebSocketHander();
    }
}

实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。

registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理, 而不实现具体的业务逻辑,可以理解为收集和任务分发中心。

setAllowedOrigins(String[] domains),允许指定的域名或IP(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。 如果不限时使用”*”号,如果指定了域名,则必须要以http或https开头。

拦截器实现

/**
 * websocket握手拦截器
 * 拦截握手前,握手后的两个切面
 */
public class MyHandShakeInterceptor implements HandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map attributes) throws Exception {
        System.out.println("准备进行握手");
        if (request instanceof ServletServerHttpRequest) {
//            attributes.put("username",userName);
        }
        return true;
    }
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception exception) {
        System.out.println("握手成功,进入服务端");
    }
}

1.beforeHandshake,在调用handler前处理方法。常用在注册用户信息,绑定WebSocketSession,在handler里根据用户信息获取WebSocketSession发送消息。

Handler处理类

/**WebSocket处理器
 * Created by qiumeng on 2017/8/7 0007.
 */
public class MyWebSocketHander extends TextWebSocketHandler {


    private static final List users = new ArrayList<>();


    //用户进入系统监听
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("成功进入了系统。。。");
        users.add(session);
    }
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage message) throws Exception {
        System.out.println("成功接收到消息");
        // 把客户端的消息解析为JSON对象
        if(message instanceof TextMessage) {


            TextMessage msg = new TextMessage("发送的数据"+message.getPayload());
            //给所有浏览器群发消息
            sendMessagesToUsers(msg);
//            this.handleTextMessage(session, (TextMessage)message);
        } else if(message instanceof BinaryMessage) {
            BinaryMessage msg = new BinaryMessage((byte[]) message.getPayload());
            //给所有浏览器群发消息
            sendMessagesToUsers(msg);
//            this.handleBinaryMessage(session, (BinaryMessage)message);
        } else {
            if(!(message instanceof PongMessage)) {
                throw new IllegalStateException("Unexpected WebSocket message type: " + message);
            }
//            this.handlePongMessage(session, (PongMessage)message);
        }


    }


    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {}
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {System.out.println("安全退出了系统");}
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
    /**
     * 给所有的用户发送消息
     */
    public void sendMessagesToUsers(WebSocketMessage  message){
        for(WebSocketSession user : users){
            try {
                //isOpen()在线就发送
                if(user.isOpen()){
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //进行实例化bean可以在其他controller实例化 调用所发送的信息
    @Bean
    public MyWebSocketHander myWebSocketHander(){
        return myWebSocketHander();
    }
}

客户端连接

这里只写出javascript代码

<script type="text/javascript">
    var receive_text = document.getElementById("up");
    var myWorker = new SharedWorker('https://localhost:8081/portal/resources/js/worker.js');
    console.log("创建sharedwork");


    myWorker.onerror = function(e)
    {
        console.log('myWorker.onerror : ' + e.message);
    }
    function myOnMessage(e) {
        receive_text.innerHTML += "
" + e.data; receive_text.scrollTop = receive_text.scrollHeight; } if(1){ // 4 绑定消息处理函数,仅设置 onmessage myWorker.port.onmessage = myOnMessage; } else{ // 5 另外一种消息绑定方式, addEventListener 和 start 配合使用 myWorker.port.addEventListener('message', myOnMessage); myWorker.port.start(); } function send(){ var ret = myWorker.port.postMessage(JSON.stringify($("#message").val())) } //页面发送消息 function sendMessage() { // var ret = myWorker.port.postMessage(stringToBytes($("#message").val())) var file=$("#file")[0].files[0]; var reader = new FileReader(); if(""==file){ alert("请选择文件") } // reader.readAsBinaryString(file) reader.readAsArrayBuffer(file) reader.onload = function (e) { if (e.target.readyState == FileReader.DONE) { var data = new Uint8Array(e.target.result); //这里有一个问题,目前没有解决 就是传输二进制数据大小的问题 好像为100万字节左右 //在大的话,目前没有找到解决办法 var jsondata=JSON.stringify(data.slice(0, 100)) var ret = myWorker.port.postMessage(jsondata); } } } </script> 下面是创建sharedWorker主线程代码work.js var count = 0; var ports = []; var webSocket = new WebSocket("ws://localhost:8081/portal/webSocketServer"); var websocketMessage=null; // 唯一的事件处理函数 onconnect = function(e) { console.log('onconnect from home'); // 1 网页建立连接获取端口 var port = e.ports[0]; ports.push({ port:port, lastRecv: new Date() }); // 2 绑定事件处理函数 port.addEventListener('message', function(e) { var ret = e.data; //因为WebSockets只能通过连接发送纯文本数据,所以对于复杂的数据结构,在通过连接发送之前,必须进行序列化 //发送消息到后台 if(""!=ret){ console.log("向websocket后台发送消息") webSocket.send(ret); } }); // 3 启动端口 port.start(); } webSocket.onopen = function(event) { console.log("websocket创建"); }; webSocket.onmessage = function(event) { console.log("websocket返回消息") websocketMessage=event.data //data的数据格式也是字符串,如果想得到其他格式的数据,必须手工解析这些数据 for(var i=0;i
点击复制链接 与好友分享!回本站首页
上一篇:字典转字符串,字符串转字典
下一篇:判断整数的正则表达式
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训

版权所有: 红黑联盟--致力于做实用的IT技术学习网站