Java 与 JavaScript 对websocket的使用

ebsocket,HTML5中新一代全双工通信协议。其底层仍然是http协议。

传统 HTTP 请求响应客户端服务器交互图

WebSocket 请求响应客户端服务器交互图

WebSocket 客户端支持

浏览器

支持情况

Chrome

Chrome version 4+支持

Firefox

Firefox version 5+支持

IE

IE version 10+支持

Safari

IOS 5+支持

Android Brower

Android 4.5+支持

webSocket消息推送例子

Java后端

pom.xml

<!-- webSocket -->  
<dependency>  
    <groupId>javax</groupId>  
    <artifactId>javaee-api</artifactId>  
    <version>7.0</version>  
</dependency> 

(tomcat7.027开始支持websocket,但是tomcat7.047开始才能使用注解形式的websoket,从该版本开始websoket被集成进入了javaee7中)

java代码:

package com.student.system.listen;  
 
import java.io.IOException;  
import java.util.concurrent.CopyOnWriteArraySet;  
 
import javax.websocket.OnClose;  
import javax.websocket.OnError;  
import javax.websocket.OnMessage;  
import javax.websocket.OnOpen;  
import javax.websocket.Session;  
import javax.websocket.server.ServerEndpoint;  
 
@ServerEndpoint("/websocket")  
public class WebSocketListen {  
 
 // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。  
 private static int onlineCount = 0;  
 
 // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识  
 private static CopyOnWriteArraySet<WebSocketListen> webSocketSet = new CopyOnWriteArraySet<WebSocketListen>();  
 
 // 与某个客户端的连接会话,需要通过它来给客户端发送数据  
 private Session session;  
 
 /** 
     * 连接建立成功调用的方法 
     *  
     * @param session 
     *            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 
     */  
 @OnOpen  
 public void onOpen(Session session) {  
 this.session = session;  
        webSocketSet.add(this); // 加入set中  
        addOnlineCount(); // 在线数加1  
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());  
    }  
 
 /** 
     * 连接关闭调用的方法 
     */  
 @OnClose  
 public void onClose() {  
        webSocketSet.remove(this); // 从set中删除  
        subOnlineCount(); // 在线数减1  
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());  
    }  
 
 /** 
     * 收到客户端消息后调用的方法 
     *  
     * @param message 
     *            客户端发送过来的消息 
     * @param session 
     *            可选的参数 
     */  
 @OnMessage  
 public void onMessage(String message, Session session) {  
        System.out.println("来自客户端的消息:" + message);  
 // 群发消息  
 for (WebSocketListen item : webSocketSet) {  
 try {  
                item.sendMessage(message);  
            } catch (IOException e) {  
                e.printStackTrace();  
 continue;  
            }  
        }  
    }  
 
 /** 
     * 发生错误时调用 
     *  
     * @param session 
     * @param error 
     */  
 @OnError  
 public void onError(Session session, Throwable error) {  
        System.out.println("发生错误");  
        error.printStackTrace();  
    }  
 
 /** 
     * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。 
     *  
     * @param message 
     * @throws IOException 
     */  
 public void sendMessage(String message) throws IOException {  
 this.session.getBasicRemote().sendText(message);  
 // this.session.getAsyncRemote().sendText(message);  
    }  
 
 public static synchronized int getOnlineCount() {  
 return onlineCount;  
    }  
 
 public static synchronized void addOnlineCount() {  
        WebSocketListen.onlineCount++;  
    }  
 
 public static synchronized void subOnlineCount() {  
        WebSocketListen.onlineCount--;  
    }  
}  

JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"  
 pageEncoding="UTF-8"%>  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>websocket</title>  
</head>  
<body>  
    Welcome<br/>  
 <input id="text" type="text"/>  
 <button onclick="send()">发送消息</button>  
 <hr/>       
 <button onclick="closeWebSocket()">关闭WebSocket连接</button>  
 <hr/>  
 <div id="message"></div>  
 <script type="text/javascript">  
    var websocket = null;  
       //判断当前浏览器是否支持WebSocket  
       if ('WebSocket' in window) {  
 websocket = new WebSocket("ws://localhost:8028/ThesisManage/websocket");  
      }  
      else {  
          alert('当前浏览器 Not support websocket')  
      }  
 
      //连接发生错误的回调方法  
 websocket.onerror = function () {  
           setMessageInnerHTML("WebSocket连接发生错误");  
      };  
 
       //连接成功建立的回调方法  
 websocket.onopen = function () {  
           setMessageInnerHTML("WebSocket连接成功");  
       }  
 
      //接收到消息的回调方法  
 websocket.onmessage = function (event) {  
           setMessageInnerHTML(event.data);  
      }  
 
       //连接关闭的回调方法  
 websocket.onclose = function () {  
          setMessageInnerHTML("WebSocket连接关闭");  
       }  
 
       //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。  
 window.onbeforeunload = function () {  
           closeWebSocket();  
       }  
 
       //将消息显示在网页上  
       function setMessageInnerHTML(innerHTML) {  
          document.getElementById('message').innerHTML += innerHTML + '<br/>';  
      }  
 
      //关闭WebSocket连接  
       function closeWebSocket() {  
           websocket.close();  
       }  
 
       //发送消息  
       function send() {  
          var message = document.getElementById('text').value;  
          websocket.send(message);  
       }  
 </script>  
</body>  
</html>  

页面效果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏分布式系统进阶

Kafka重置消费的OffsetKafka源码分析-汇总

2352
来自专栏iOS 开发杂谈

浅谈如何在项目中处理页面中的多个网络请求

在开发中很多时候会有这样的场景,同一个界面有多个请求,而且要在这几个请求都成功返回的时候再去进行下一操作,对于这种场景,如何来设计请求操作呢?今天我们就来讨论一...

1412
来自专栏子勰随笔

Android开发调试常用工具

2488
来自专栏编程坑太多

『中级篇』k8s的NodePort类型Service以及Label的简单实用(68)

823
来自专栏ionic3+

自定义Cordova插件详解

在混合式应用中,我们通过现有的Cordova插件,可以轻松的在 H5 上调用手机native的功能。现有的Cordova插件能满足平时大部分的开发需求,然而,有...

1063
来自专栏Python爬虫与算法进阶

强大的异步爬虫 with aiohttp

看到现在网络上大多讲的都是requests、scrapy,却没有说到爬虫中的神器:aiohttp

1002
来自专栏我是攻城师

Hadoop2.7.1和Hbase0.98添加LZO压缩

2817
来自专栏程序员与猫

Elasticsearch 健康状态处理

笔者在自己的 ubuntu 服务器上使用 GET /_cat/health?v 命令时,返回值如下所示 ? 可以看到集群状态为 yellow,这是什么意思呢?原...

1989
来自专栏hotqin888的专栏

beego利用casbin进行权限管理——第一节 起步、测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

1431
来自专栏Jerry的SAP技术分享

Java Web项目,Android和微信小程序的初始页面配置

我们在Eclipse里开了Java Web项目之后,Run As Tomcat或者Apache服务器,本地运行,如果直接用http://localhost:80...

1611

扫码关注云+社区