websocket可以实现服务端的消息推送,而不必在客户端轮询,大大的节省的资源,对于实时通讯来说简直是个大喜讯。

在上一篇文章中介绍了协议握手,这篇文章将通过实现简单的群聊来帮助进一步了解websocket。

注意:1.JavaEE版本为7.0

2.tomcat版本为8.0

3.不需要额外导入其他的jar包

由于websocket不支持低版本的javaEE和tomcat,所以必须符合上述条件,我是在Myeclipse2014 的IDE中进行编码的。

为了尽可能的使代码简洁以便更好的理解,所以代码中有些地方可能不全面,但不影响学习websocket。

首先是WebSocketServer类:

package socket;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet; import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/socket",configurator=GetHttpSessionConfigurator.class)
public class WebSocketServer { private static final Set<WebSocketServer> onlineUsers =
new CopyOnWriteArraySet<WebSocketServer>(); //静态变量 存储在线用户
private HttpSession httpSession;
private Session session;
private String name; @OnMessage
public void onMessage(String message, Session session)
throws IOException, InterruptedException { //将客户端传来的消息发送给所有在线用户
sendMessageToAllOnline(session,this.name+" : "+message); //在控制台打印当前在线用户
for(WebSocketServer webSocketServer:onlineUsers){
System.out.print(webSocketServer.name+" ");
}
System.out.println();
} @OnOpen
public void onOpen (Session session, EndpointConfig config) throws IOException {
System.out.println("Client connected"); this.session = session;
this.httpSession = (HttpSession) config.getUserProperties()
.get(HttpSession.class.getName());
this.name=(String) httpSession.getAttribute("name");
onlineUsers.add(this); //将用户信息添加到在线用户序列中 //将上线消息发送给所有在线用户
sendMessageToAllOnline(session,this.name+" 上线了"); } @OnClose
public void onClose(Session session) throws IOException{
onlineUsers.remove(this);
System.out.println("Connection closed");
//将下线消息发送给所有在线用户
sendMessageToAllOnline(session,this.name+" 下线了"); }
/**
* 发送信息给所有在线用户.
* @param session
* @param message
*/
public void sendMessageToAllOnline(Session session,String message) throws IOException{
for (Session sess : session.getOpenSessions()){
if (sess.isOpen()){
sess.getBasicRemote().sendText(message);
}
}
}
}

由于这里边的session和平时使用的httpsession不是同一个,所以为了可以获取httpsession以便获取当前用户的信息,所以需要下面的类:

package socket;

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
/**
* 为获取httpSession提供支持
* @author nagsh
*
*/
public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator{
@Override
public void modifyHandshake(ServerEndpointConfig config,
HandshakeRequest request,
HandshakeResponse response){
HttpSession httpSession = (HttpSession)request.getHttpSession();
config.getUserProperties().put(HttpSession.class.getName(),httpSession);
}
}

该类在websocket的@ServerEndpoint注解中引用。

为了可以获取登陆用户的信息以便实现群聊,简单的写了一个登陆,会将用户信息存到session中

客户端:

login.html

<!DOCTYPE html>
<html>
<head>
<title>login.html</title>
</head> <body>
<form action="servlet/LoginServlet" method="post">
姓名:<input type="text" name="name"/>
<input type="submit">
</form>
</body>
</html>

服务端:

package socket;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 处理用户的登陆.
* @author nagsh
*
*/
public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html");
PrintWriter out = response.getWriter(); String name = request.getParameter("name");
//将当前用户的信息存入session中
request.getSession().setAttribute("name",name);
//重定向到聊天界面
response.sendRedirect("/websockettest/socketClient.jsp");
} }

然后下面是简单的聊天界面(勿吐槽哈) 该页面是在上篇文章实现握手的页面基础上简单修改的:

socketClient.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE html>
<html>
<head>
<title>Testing websockets</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
</head>
<script type="text/javascript">
/* 申请一个WebSocket对象,参数是需要连接的服务器端的地址 */
var webSocket = new WebSocket('ws://localhost:8080/websockettest/socket'); /* 如果出现连接、处理、接收、发送数据失败的时候就会触发onerror事件 */
webSocket.onerror = function(event) {
onError(event)
}; /* 当websocket创建成功时,即会触发onopen事件 */
webSocket.onopen = function(event) {
onOpen(event)
}; /* 当客户端收到服务端发来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据 */
webSocket.onmessage = function(event) {
onMessage(event)
}; /* 当客户端收到服务端发送的关闭连接的请求时,触发onclose事件 */
webSocket.onclose = function(event) {
onMessage(event)
}; function onMessage(event) {
$("#messages").append(event.data+"<br/>");
} function onOpen(event) {
$("#messages").append("成功建立连接...<br/>");
$("#messages").append(event.data); } function onClose(event) {
$("#messages").append(event.data);
} function onError(event) {
alert("error");
} //发送信息
function send(){
var content = $("#content").val();
webSocket.send(content);
}
</script>
<body> <div id="messages"></div>
<input type="text" id="content">
<input type="button" value="发送" onclick="send()"> </body>
</html>

版权声明:本文为博主原创文章,未经博主允许不得转载。

websocket(二)--简单实现网页版群聊的更多相关文章

  1. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  2. Socket通信 简单实现私聊、群聊(dos命令下)

    很久以前的一个Demo,这里服务器只做转发功能,根据ID地址和端口号来标识身份,群聊和私聊只是简单实现, 服务器代码如下: import java.util.*; import java.io.*; ...

  3. Linux Linux程序练习十二(select实现QQ群聊)

    //头文件--helper.h #ifndef _vzhang #define _vzhang #ifdef __cplusplus extern "C" { #endif #de ...

  4. 基于WebSocket实现网页版聊天室

    WebSocket ,HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,其使用简单,应用场景也广泛,不同开发语言都用种类繁多的实现,仅Java体系中,Tomcat,Jetty,Sp ...

  5. 新开源HTML5单文件网页版ACME客户端,可在线申请Let's Encrypt、ZeroSSL免费HTTPS多域名通配符泛域名SSL/TLS证书(RSA/ECC/ECDSA)

    目录 开源项目的起源 项目地址 使用方法 第一步:选择Let's Encrypt.ZeroSSL或其他证书颁发机构 第二步:证书配置,填写域名 第三步:完成域名所有权的验证 第四步:下载保存证书PEM ...

  6. flask + websocket实现简单的单聊和群聊

    单聊 from flask import Flask,request,render_template from geventwebsocket.handler import WebSocketHand ...

  7. websocket 实现简单网页版wechat

    1.群聊 web - socket--基于TCP/UDP http - 无状态的短链接 长连接:客户端和服务器保持永久性的链接,除非有一方主动断开, 轮询:客户端和服务端不断连接,然后断开,请求响应; ...

  8. WebSocket+Java 私聊、群聊实例

    前言 之前写毕业设计的时候就想加上聊天系统,当时已经用ajax长轮询实现了一个(还不懂什么是轮询机制的,猛戳这里:https://www.cnblogs.com/hoojo/p/longPolling ...

  9. Springboot整合WebSocket实现网页版聊天,快来围观!

随机推荐

  1. MongoDB下载安装测试及使用

    1.下载安装 64位:mongodb-win32-x86_64-enterprise-windows-64-2.6.4-signed.msi 余数为1的 db.collection.find({ &q ...

  2. SharePoint 2007 列表页定制--4个默认页定制

    以"简单的领导简介"为例,欢迎大家指正 背景:项目中需要有领导简介的模块,就开始制作领导简介,本来很简单,有一个列表就可以,然后在前台展示出来,但是客户看到我们的效果,尤其输入领导 ...

  3. ELF 动态链接 - so 的 .dynamic 段

    动态链接文件中最重要的段就是 .dynamic段 这个段里保存了动态链接器需要的最基本的信息 比如:1.  依赖于哪些共享对象, d_tag = DT_NEED,  d_ptr 表示共享对象文件名 2 ...

  4. pandas数据处理基础——筛选指定行或者指定列的数据

    pandas主要的两个数据结构是:series(相当于一行或一列数据机构)和DataFrame(相当于多行多列的一个表格数据机构). 本文为了方便理解会与excel或者sql操作行或列来进行联想类比 ...

  5. aside元素

    aside元素用来表示当前页面或文章的附属信息部分,它可以包含与当前页面或主要内容相关的引用.侧边栏.广告.导航条,以及其他类似的有别于主要内容的部分. aside元素主要有以下两种使用方法: 1.包 ...

  6. java 深入理解内部类以及之间的调用关系

    什么是内部类 内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的.内部类可为静态,可用protected和private修饰(而外部类只能使用public和 ...

  7. access登录校验代码二

    ' 这一段是用来检查有没有输入用户名或密码的If IsNull(Trim(Me.username )) ThenDoCmd.BeepMsgBox ("请输入用户名称! ")Else ...

  8. Web开发相关工具收集

    FireFox相关: FireBug/GreaseMonkey/Yslow/WebDeveloperSelenium:Web应用程序测试的工具--  http://seleniumhq.org/  h ...

  9. 解决ubuntu unity下gvim菜单消失的问题

    #问题描述:在终端下用gvim 指令打开 gvim就不显示菜单.在不启用unity的桌面环境下用终端打开gvim是有菜单的.从程序菜单中打开gvim是显示菜单的.用sudo打开gvim也可以显示菜单, ...

  10. Android反编译和再打包神器:Apktool

    首先推荐一下这东东,官网:https://ibotpeaches.github.io/Apktool/ 安装.使用之类的看官方文档吧,写这个博客主要是mark一下这东西. 这玩意只能供打包党来用,要想 ...