分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

WebSocket 示例

发布时间:2023-09-06 01:31责任编辑:熊小新关键词:Web

websocket应运而生

在WebSocket规范提出之前,开发人员若要实现带有即时通信、实时数据、订阅推送等功能的应用实时性较强的功能,经常会使用的解决方法是 Comet。

Comet是一种服务器向页面推送数据的技术。 有两种实现 Comet 的方式: 长轮询和流。长轮询是传统轮询(也称为短轮询)的一个翻版,即浏览

器定时向服务器发送请求,看有没有更新的数据。图 1 展示的是短轮询的时间线。

                                       图1
长轮询把短轮询颠倒了一下。页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到
有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页
面打开期间一直持续不断。图 2 展示了长轮询的时间线。

             图2

无论是短轮询还是长轮询,浏览器都要在接收数据之前,先发起对服务器的连接。两者最大的区别在于服务器如何发送数据。

短轮询是服务器立即发送响应,无论数据是否有效,而长轮询是等待发送响应。

轮询的优势是所有浏览器都支持,因为使用 XHR 对象和 setTimeout()就能实现。而你要做的就是决定什么时候发送请求。

第二种流行的 Comet 实现是 HTTP 流。流不同于上述两种轮询,因为它在页面的整个生命周期内只
使用一个 HTTP 连接。具体来说,就是浏览器向服务器发送一个请求,而服务器保持连接打开,然后周
期性地向浏览器发送数据。

这两种技术都是基于请求-应答模式,都不算是真正意义上的实时技术;它们的每一次请求、应答,都浪费了一定流量在相同的头部信息上,并且开发复杂度也较大。

伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,Web Sockets 的目标是在一个单独的持久连接上提供全双工、双向通信。在 JavaScript 中创建了 Web Socket 之后,会有一个 HTTP 请求发送到浏览器以发起连接。在取得服务器响应后,建立的连接会使用 HTTP 升级从 HTTP 协议交换为 Web

Socket 协议。也就是说,使用标准的 HTTP 服务器无法实现 Web Sockets,只有支持这种协议的专门服
务器才能正常工作。
 

 websocket 示例

 客户端(Web主页)代码:

 1 <%@ page language="java" pageEncoding="UTF-8" %> 2 <!DOCTYPE html> 3 <html> 4 <head> 5 ????<title>Java后端WebSocket的Tomcat实现</title> 6 </head> 7 <body> 8 ????Welcome<br/><input id="text" type="text"/> 9 ????<button onclick="send()">发送消息</button>10 ????<hr/>11 ????<button onclick="closeWebSocket()">关闭WebSocket连接</button>12 ????<hr/>13 ????<div id="message"></div>14 </body>15 16 <script type="text/javascript">17 ????var websocket = null;18 ????//判断当前浏览器是否支持WebSocket19 ????if (‘WebSocket‘ in window) {20 ????????websocket = new WebSocket("ws://localhost:8080/websocket");21 ????}22 ????else {23 ????????alert(‘当前浏览器 Not support websocket‘)24 ????}25 26 ????//连接发生错误的回调方法27 ????websocket.onerror = function () {28 ????????setMessageInnerHTML("WebSocket连接发生错误");29 ????};30 31 ????//连接成功建立的回调方法32 ????websocket.onopen = function () {33 ????????setMessageInnerHTML("WebSocket连接成功");34 ????}35 36 ????//接收到消息的回调方法37 ????websocket.onmessage = function (event) {38 ????????setMessageInnerHTML(event.data);39 ????}40 41 ????//连接关闭的回调方法42 ????websocket.onclose = function () {43 ????????setMessageInnerHTML("WebSocket连接关闭");44 ????}45 46 ????//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。47 ????window.onbeforeunload = function () {48 ????????closeWebSocket();49 ????}50 51 ????//将消息显示在网页上52 ????function setMessageInnerHTML(innerHTML) {53 ????????document.getElementById(‘message‘).innerHTML += innerHTML + ‘<br/>‘;54 ????}55 56 ????//关闭WebSocket连接57 ????function closeWebSocket() {58 ????????websocket.close();59 ????}60 61 ????//发送消息62 ????function send() {63 ????????var message = document.getElementById(‘text‘).value;64 ????????websocket.send(message);65 ????}66 </script>67 </html>

  Java Web后端代码

 1 package me.gacl.websocket; 2 ?3 import java.io.IOException; 4 import java.util.concurrent.CopyOnWriteArraySet; 5 ?6 import javax.websocket.*; 7 import javax.websocket.server.ServerEndpoint; 8 ?9 /**10 ?* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,11 ?* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端12 ?*/13 @ServerEndpoint("/websocket")14 public class WebSocketTest {15 ????//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。16 ????private static int onlineCount = 0;17 18 ????//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识19 ????private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();20 21 ????//与某个客户端的连接会话,需要通过它来给客户端发送数据22 ????private Session session;23 24 ????/**25 ?????* 连接建立成功调用的方法26 ?????* @param session ?可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据27 ?????*/28 ????@OnOpen29 ????public void onOpen(Session session){30 ????????this.session = session;31 ????????webSocketSet.add(this); ????//加入set中32 ????????addOnlineCount(); ??????????//在线数加133 ????????System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());34 ????}35 36 ????/**37 ?????* 连接关闭调用的方法38 ?????*/39 ????@OnClose40 ????public void onClose(){41 ????????webSocketSet.remove(this); ?//从set中删除42 ????????subOnlineCount(); ??????????//在线数减143 ????????System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());44 ????}45 46 ????/**47 ?????* 收到客户端消息后调用的方法48 ?????* @param message 客户端发送过来的消息49 ?????* @param session 可选的参数50 ?????*/51 ????@OnMessage52 ????public void onMessage(String message, Session session) {53 ????????System.out.println("来自客户端的消息:" + message);54 ????????//群发消息55 ????????for(WebSocketTest item: webSocketSet){56 ????????????try {57 ????????????????item.sendMessage(message);58 ????????????} catch (IOException e) {59 ????????????????e.printStackTrace();60 ????????????????continue;61 ????????????}62 ????????}63 ????}64 65 ????/**66 ?????* 发生错误时调用67 ?????* @param session68 ?????* @param error69 ?????*/70 ????@OnError71 ????public void onError(Session session, Throwable error){72 ????????System.out.println("发生错误");73 ????????error.printStackTrace();74 ????}75 76 ????/**77 ?????* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。78 ?????* @param message79 ?????* @throws IOException80 ?????*/81 ????public void sendMessage(String message) throws IOException{82 ????????this.session.getBasicRemote().sendText(message);83 ????????//this.session.getAsyncRemote().sendText(message);84 ????}85 86 ????public static synchronized int getOnlineCount() {87 ????????return onlineCount;88 ????}89 90 ????public static synchronized void addOnlineCount() {91 ????????WebSocketTest.onlineCount++;92 ????}93 94 ????public static synchronized void subOnlineCount() {95 ????????WebSocketTest.onlineCount--;96 ????}97 }

 运行效果

  

附上源码下载链接:https://files.cnblogs.com/files/sunTin/javaWebSocket.zip

 参考博客来源:http://www.cnblogs.com/xdp-gacl/p/5193279.html

WebSocket 示例

原文地址:http://www.cnblogs.com/sunTin/p/8075237.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved