使用WebSocket实现即时通讯(一个群聊的聊天室)

随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。

传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式对于信息变化不频繁的Web应用来说造成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应用。在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,经常会使用折衷的解决方法:轮询(polling)和Comet技术。其实后者本质上也是一种轮询,只不过有所改进。

轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动。明显地,这种方法会导致过多不必要的请求,浪费流量和服务器资源。

Comet技术又可以分为长轮询和流技术。长轮询改进了上述的轮询技术,减小了无用的请求。它会为某些数据设定过期时间,当数据过期后才会向服务端发送请求;这种机制适合数据的改动不是特别频繁的情况。流技术通常是指客户端使用一个隐藏的窗口与服务端建立一个HTTP长连接,服务端会不断更新连接状态以保持HTTP长连接存活;这样的话,服务端就可以通过这条长连接主动将数据发送给客户端;流技术在大并发环境下,可能会考验到服务端的性能。

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

**伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,使B/S模式具备了C/S模式的实时通信能力。**WebSocket的工作流程是这样的:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过TCP连接传输数据。因为WebSocket连接本质上是TCP连接,不需要每次传输都带上重复的头部数据,所以它的数据传输量比轮询和Comet技术小了很多。本文不详细地介绍WebSocket规范,主要介绍下WebSocket在Java Web中的实现,并使用WebSocket实现一个聊天室。

JavaEE 7中出了JSR-356:Java API for WebSocket规范。不少Web容器,如Tomcat,Nginx,Jetty等都支持WebSocket。Tomcat从7.0.27开始支持WebSocket,从7.0.47开始支持JSR-356。下面的代码也必须运行在Tomcat7.0.27以上的版本。

WebSocket服务端的代码

//该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。
@ServerEndpoint("/webSocket")
public class WebSocketDemo {
 // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
 private static final AtomicInteger onlineCount = new AtomicInteger(0);
 // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
 private static CopyOnWriteArraySet<WebSocketDemo> webSocketSet = new CopyOnWriteArraySet<WebSocketDemo>();
 //定义一个记录客户端的聊天昵称
 private final String nickname;
 // 与某个客户端的连接会话,需要通过它来给客户端发送数据
 private Session session;

 public WebSocketDemo() {
  nickname = "访客"+onlineCount.getAndIncrement();
 }
 /*
  *使用@Onopen注解的表示当客户端链接成功后的回掉。参数Session是可选参数
  这个Session是WebSocket规范中的会话,表示一次会话。并非HttpSession
  */
 @OnOpen
 public void onOpen(Session session) {
  this.session = session;
  webSocketSet.add(this);
  String message = String.format("[%s,%s]",nickname,"加入聊天室");
  broadcast(message);
  System.out.println("onOpen");
 }
/*
  *使用@OnMessage注解的表示当客户端发送消息后的回掉,第一个参数表示用户发送的数据。参数Session是可选参数,与OnOpen方法中的session是一致的
  */
 @OnMessage
 public void onMessage(String message,Session session){
 //这里当然会打印true
  System.out.println(this.session==session);
  broadcast(String.format("%s:%s",nickname,filter(message)));
 }
/*
*用户断开链接后的回调,注意这个方法必须是客户端调用了断开链接方法后才会回调
*/
 @OnClose
 public void onClose() {
  webSocketSet.remove(this);
  String message = String.format("[%s,%s]",nickname,"离开了聊天室链接");
  broadcast(message);
 }
 //完成群发
 private void broadcast(String info){
  for(WebSocketDemo w:webSocketSet){
   try {
    synchronized (WebSocketDemo.class) {
     w.session.getBasicRemote().sendText(info);
    }
   } catch (IOException e) {
    System.out.println("向客户端"+w.nickname+"发送消息失败");
    webSocketSet.remove(w);
    try {
     w.session.close();
    } catch (IOException e1) {}
    String message = String.format("[%s,%s]",w.nickname,"已经断开链接");
    broadcast(message);
   }

  }
 }
 //对用户的消息可以做一些过滤请求,如屏蔽关键字等等。。。
 public static String filter(String message){
  if(message==null){
   return null;
  }
  return message;
 }
}

客户端(Web主页)代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
 var ws = new WebSocket("ws://localhost:8080/WebSocketTest/webSocket");
 /*
  *监听三种状态的变化 。js会回调
  */
 ws.onopen = function(message) {

 };
 ws.onclose = function(message) {

 };
 ws.onmessage = function(message) {
  showMessage(message.data);
 };
 //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
  ws.close();
 };
 //关闭连接
 function closeWebSocket() {
  ws.close();
 }
 //发送消息
 function send() {
  var input = document.getElementById("msg");
  var text = input.value;
  ws.send(text);
  input.value = "";
 }
 function showMessage(message) {
  var text = document.createTextNode(message);
  var br = document.createElement("br")
  var div = document.getElementById("showChatMessage");
  div.appendChild(text);
  div.appendChild(br);
 }
</script>
</head>
<body>
 <div
  style="width: 600px; height: 240px; overflow-y: auto; border: 1px solid #333;"
  id="show">
  <div id="showChatMessage"></div>
  <input type="text" size="80" id="msg" name="msg" placeholder="输入聊天内容" />
  <input type="button" value="发送" id="sendBn" name="sendBn"
   onclick="send()">
</body>
</html>

如上就完成了一个具有群聊功能的聊天室。验证过程中发现使用WebSocket能够完成跨域请求。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • NetCore WebSocket即时通讯示例
  • Android使用Websocket实现聊天室
  • swoole和websocket简单聊天室开发
  • express框架实现基于Websocket建立的简易聊天室
  • 基于Tomcat7、Java、WebSocket的服务器推送聊天室实例
  • 用java WebSocket做一个聊天室
  • golang基于websocket实现的简易聊天室程序
  • 使用Java和WebSocket实现网页聊天室实例代码
  • JavaEE7+Websockets+GlassFish4打造聊天室
(0)

相关推荐

  • NetCore WebSocket即时通讯示例

    NetCore WebSocket 即时通讯示例,供大家参考,具体内容如下 1.新建Netcore Web项目 2.创建简易通讯协议 public class MsgTemplate { public string SenderID { get; set; } public string ReceiverID { get; set; } public string MessageType { get; set; } public string Content { get; set; } } Se

  • express框架实现基于Websocket建立的简易聊天室

    最近想写点有意思的,所以整了个这个简单的不太美观的小玩意 首先你得确认你的电脑装了node,然后就可以按照步骤 搞事情了~~ 1.建立一个文件夹 2.清空当前文件夹地址栏,在文件夹地址栏中输入cmd.exe 3.我们需要下载点小东西 ,需要在命令行输入 npm install express 回车 等待一会 npm install express-session 回车 等待一会 npm install ejs 回车 等待一会 npm install socket.io 回车 等待一会 叮~~~

  • golang基于websocket实现的简易聊天室程序

    本文实例讲述了golang基于websocket实现的简易聊天室.分享给大家供大家参考,具体如下: 先说点无关的,最近忙于工作没有更新博客,今天休息顺便把golang websocket研究了一下,挺好玩的,写了一个聊天室,分享给大家. websocket包 : code.google.com/p/go.net/websocket 文档 : http://go.pkgdoc.org/code.google.com/p/go.net/websocket 首先安装websocket包 复制代码 代码

  • Android使用Websocket实现聊天室

    最近的项目中要实现一个聊天的功能,类似于斗鱼TV的聊天室功能,与服务器端人商量后决定用WebSocket来做,但是在这之前我只知道Socket但是听都没有听过WebSocket,但是查看了相关的材料以后发现实现一个聊天室其实是很简单的!下面我们先来看看WebSocket. Autobahn|Android 是由Autobahn开发一个开源的Java/Android网络库,实现了WebSocket协议和Web应用程序消息传输协议来创建本地移动的WebSocket/ WAMP的客服端. WebSoc

  • 基于Tomcat7、Java、WebSocket的服务器推送聊天室实例

    前言 HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用.以前的服务器消息推送大部分采用的都是"轮询"和"长连接"技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高.WebSocket技术对只会产生很小的开销,并且实时性特别高.下面就开始讲解如何利用WebSocket技术开发聊天室.在这个实例中,采用的是Tomcat7服务器,每个服务器对于WebSoc

  • 使用Java和WebSocket实现网页聊天室实例代码

    在没介绍正文之前,先给大家介绍下websocket的背景和原理: 背景 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更

  • swoole和websocket简单聊天室开发

    首先,我想说下写代码的一些习惯,第一,任何可配置的参数或变量都要写到一个config文件中.第二,代码中一定要有日志记录和完善的报错并记录报错.言归正传,swoole应该是每个phper必须要了解的,它号称重新定义了php.此聊天室利用了swoole高并发并且异步非阻塞的特点提高了程序的性能. 首先,定义一个 swoole_lock 和 swoole_websocket_server ,并且配置参数,具体参数详情可以去swoole官网查看. public function start() { $

  • 用java WebSocket做一个聊天室

    最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了. 先看图: 实现了多客户机进行实时通讯. 下面看代码项目结构图:很简单,就1个类,1个页面 然后看具体代码 先看后端代码 package com.main; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.

  • JavaEE7+Websockets+GlassFish4打造聊天室

    在客户机和服务器之间建立单一的双向连接,这就意味着客户只需要发送一个请求到服务端,那么服务端则会进行处理,处理好后则将其返回给客户端,客户端则可以在等待这个时间继续去做其他工作,整个过程是异步的.在本系列教程中,将指导用户如何在JAVA EE 7的容器GlassFish 4中,使用JAVA EE 7中的全新的解析Json API(JSR-353),以及综合运用jQuery和Bootstrap.本文要求读者有一定的HTML 5 Websocket的基础原理知识. 效果图 我们先来看下在完成这个教程

  • 使用WebSocket实现即时通讯(一个群聊的聊天室)

    随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据. 传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据:这种客户端是主动方,服务端是被动方的传统Web模式对于信息变化不频繁的Web应用来说造成的麻烦

  • Android Flutter基于WebSocket实现即时通讯功能

    目录 前言 联系人界面构建 聊天界面的实现 消息界面的 MultiProvider 运行效果 前言 我们在前面花了很大篇幅介绍 Provider 状态管理,这是因为在 Flutter 中,Provider 是众多状态管理插件的首选.本篇以即时聊天为例,来讲述 Provider 的综合应用,也算是 Provider 状态管理系列的终结篇.本篇涉及的内容如下: 联系人界面的构建: 聊天界面的简单实现; StreamProvider 接收 Socket流数据并自动通知界面刷新; MultiProvid

  • 使用Android WebSocket实现即时通讯功能

    最近做这个功能,分享一下.即时通讯(Instant Messaging)最重要的毫无疑问就是即时,不能有明显的延迟,要实现IM的功能其实并不难,目前有很多第三方,比如极光的JMessage,都比较容易实现.但是如果项目有特殊要求(如不能使用外网),那就得自己做了,所以我们需要使用WebSocket. WebSocket WebSocket协议就不细讲了,感兴趣的可以具体查阅资料,简而言之,它就是一个可以建立长连接的全双工(full-duplex)通信协议,允许服务器端主动发送信息给客户端. Ja

  • SpringBoot+WebSocket实现即时通讯的方法详解

    目录 环境信息 服务端实现 导入依赖 创建配置类 创建一个注解式的端点并在其中通过配套注解声明回调方法 服务端主动发送消息给客户端 客户端实现 Java客户端实现 在前端环境(vue)中使用websocket 环境信息 名称 版本号 Spring Boot 2.4.5 Idea 2021.3.2 服务端实现 导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp

  • Go语言实现一个简单的并发聊天室的项目实战

    目录 写在前面 并发聊天服务器 具体代码 服务端 客户端 总结 写在前面 Go语言在很多方面天然的具备很多便捷性,譬如网络编程,并发编程.而通道则又是Go语言实现并发编程的重要工具,因为其承担着通道之间互相通信的重任.并且因为其本身就是并发安全的,所以在某些场景下是非常好用的. 并发聊天服务器 这里主要是实现一个简单的并发聊天服务器.首先,客户端可以在服务器中注册自己的信息(登录以及退出),客户端发出的所有的信息由服务器向各个客户端进行转发,或者换句话说是广播. 具体代码 服务端 说的再多,没有

  • Android即时通讯设计(腾讯IM接入和WebSocket接入)

    目录 一.前言 二.腾讯IM接入 1.准备工作 2.初始化工作 用户登录 3.群聊相关 4.消息收发相关 三.WebSocket接入 1.WebSocket介绍 2.服务端相关 3.客户端相关 四.列表设计的一些细节 1.handle的使用 2.消息的获取和RecycleView的刷新 3.关于消息item的设计细节 五.项目使用的接口和地址 六.总结 一.前言 之前项目的群聊是用数据库直接操作的,体验很差,消息很难即时反馈,所以最后考虑到了使用腾讯的IM完成群聊的接入,不过中途还是有点小坎坷的

  • Nodejs + Websocket 指定发送及群聊的实现

     目的 通过nodejs + ws (Websocket) 实现点对点发送及群聊发送 项目搭建直接跳过,这里列举一下用到的插件 yarn add ws WebSocket 话不多说,直接上码 对比上一篇文章 << Nodejs+MongoDB 搭建服务( demo ) >> server.js 主要是增加了ws的引用, webSocket 点对点也好,群聊也好,主要是用到一个方法 clients 它的作用就是存储了连接, 我们可以通过对每一个连接增加标识,然后根据接收到的信息进行解

  • 用Flash和XML来构造一个聊天室

    点击这里下载源文件 前面的教程我们介绍了Flash与XML结合使用的原理以及一个论坛的实现,下面我们继续结合Flash与XML来实现一个简单的聊天室,有在线聊天.在线人员名单.在线时间.简单的管理操作等功能.根据需要在此基础上稍作修改,就可以实现一个功能比较完备的聊天室了. 一.原理 用Flash和XML来构造聊天室,跟直接用Flash和Asp来构造聊天室的基本原理是一样的.都是先在Flash端发送一个XML请求到服务器端,然后等待从服务器端的XML返回值,当值返回Flash端后,解释所返回的X

  • vue + socket.io实现一个简易聊天室示例代码

    vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了.功能虽然不多,但还是有收获.设计和实现思路较为拙劣,恳请各位道友指正. 可以达到的需求 能查看在线用户列表 能发送和接受消息 使用到的框架和库 socket.io做为实时通讯基础 vuex/vue:客户端Ui层使用 Element-ui:客户端Ui组件 类文件关系图 服务端: 客户端: 服

  • ASP建立一个简单的聊天室

    经过一个阶段的asp学习,下面我们结合所学过的内容建立一个最简单的聊天室,虽然很简单,但是大家可以通过它来掌握一个聊天室建立的基本过程,并且可以不断的完善其功能. 下面介绍其主要步骤: 1,添加Global.asa文件里面的代码.这部分代码主要处理Application_onStart事件,在此事件中,定义了一个有15个元素的数据,并把它赋给了一个Application对象的属性.Global.asa文件的内容如下. <SCRIPT LANGUAGE="VBScript" RUN

随机推荐