Java WebSocket实现简易聊天室
一、Socket简介
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。Socket的英文原义是“孔”或“插座”,作为UNIX的进程通信机制。Socket可以实现应用程序间网络通信。
Socket可以使用TCP/IP协议或UDP协议。
TCP/IP协议
TCP/IP协议是目前应用最为广泛的协议,是构成Internet国际互联网协议的最为基础的协议,由TCP和IP协议组成:
TCP协议:面向连接的、可靠的、基于字节流的传输层通信协议,负责数据的可靠性传输的问题。
IP协议:用于报文交换网络的一种面向数据的协议,主要负责给每台网络设备一个网络地址,保证数据传输到正确的目的地。
UDP协议
UDP特点:无连接、不可靠、基于报文的传输层协议,优点是发送后不用管,速度比TCP快。
二、WebSocket简介与消息推送
B/S架构的系统多使用HTTP协议,HTTP协议的特点:
1 无状态协议
2 用于通过 Internet 发送请求消息和响应消息
3 使用端口接收和发送消息,默认为80端口
底层通信还是使用Socket完成。
HTTP协议决定了服务器与客户端之间的连接方式,无法直接实现消息推送(F5已坏),一些变相的解决办法:
双向通信与消息推送
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。 优点:后端程序编写比较容易。 缺点:请求中有大半是无用,浪费带宽和服务器资源。 实例:适于小型应用。
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。 优点:在无消息的情况下不会频繁的请求,耗费资小。 缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。 Comet异步的ashx,实例:WebQQ、Hi网页版、Facebook IM。
长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。 优点:消息即时到达,不发无用请求;管理起来也相对便。 缺点:服务器维护一个长连接会增加开销。 实例:Gmail聊天
Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。 优点:实现真正的即时通信,而不是伪即时。 缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙。 实例:网络互动游戏。
Websocket:
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
特点:
事件驱动
异步
使用ws或者wss协议的客户端socket
能够实现真正意义上的推送功能
缺点:
少部分浏览器不支持,浏览器支持的程度与方式有区别。
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
三、界面如下:
四、实现代码
1、客户端CSS样式(ChatClient.css):
#divMessage{width:750px;height:550px;margin:5px;background-image:url(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1533792134030&di=14e6b1be8d569d7dcb570ed21bbd218d&imgtype=0&src=http%3A%2F%2Ffb.topitme.com%2Fb%2F28%2F64%2F1129884950a4e6428bo.jpg);background-position:-150px 0px;float:left;color:black;font-size:18px;font-family:新宋体;}#divOperation{width:400px;height:450px;float:right;}.green{color:green;}.red{color:red;}img{width:100px;height:100px;}span{font-size:24px;font-family:华文琥珀;}#showAllUserName{width:150px;height:550px;background-image:url(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1533792134030&di=14e6b1be8d569d7dcb570ed21bbd218d&imgtype=0&src=http%3A%2F%2Ffb.topitme.com%2Fb%2F28%2F64%2F1129884950a4e6428bo.jpg);float:left;font-size:18px;font-family:新宋体;margin:5px;}input[type=button]{width:80px;height:30px;margin:5px;}
2、客户端界面:
<!DOCTYPE html> <htmllang="en"> <head><metacharset="UTF-8"><title>聊天界面</title><linkrel="stylesheet"href="css/ChatClient.css"> </head> <body><divstyle="OVERFLOW-Y: auto; OVERFLOW-X:hidden;"id="showAllUserName"><pstyle="color:green;font-family: 华文琥珀;"> 在线用户:</p></div><divstyle="OVERFLOW-Y: auto; OVERFLOW-X:hidden;"id="divMessage"></div><divid="divOperation"><p>昵称:<inputstyle="width:120px;line-height:20px;"type="text"maxlength="5"id="txtUserName" /></p><spanid="spanUserName"class="red">未连接</span></p><p>消息输入(可输入HTML代码):<textareaid="txtMessage"cols="50"rows="4"></textarea></p><p><inputtype="button"id="btnConnection"value="连接" /><spanid="spanMessage"></span><inputtype="button"disabled id="btnSend"value="发送"/><inputtype="button"disabled id="btnClose"value="关闭" /></p></div><scripttype="text/javascript"src="js/jquery-1.11.3.js"></script><script>varsocket;if(typeof(WebSocket)=="undefined"){alert("您的浏览器不支持WebSocket");}//连接点击 $("#btnConnection").click(function(){varname=$("#txtUserName").val();if(name==null ||name==""){$("#spanUserName").text("用户名格式错误!").prop("class","red");return;}//实例化WebSocket,指定要连接的服务器地址与端口 socket= newWebSocket("ws://localhost:8080/ws/"+name);//打开事件 socket.onopen= function() {console.log("Socket已打开");$("#spanUserName").text("已连接").prop("class","green");$("#btnConnection").prop("disabled",true);$("#btnSend").prop("disabled",false);$("#btnClose").prop("disabled",false);$("#txtUserName").prop("disabled",true);}//获得消息事件 socket.onmessage= function(msg) {varsign=msg.data.substring(0,msg.data.indexOf("&"));varcontent=msg.data.substring(msg.data.indexOf("&")+1);if(sign=="userAllName"){//所有在线用户信息处理varuserNames=content.split(",");//除了第一个p标签,其余清空 $("#showAllUserName p:gt(0)").remove();for(vari=0;i<userNames.length;i++){$("#showAllUserName").append($("<p/>").html(" "+userNames[i]));}}else if(sign=="userMessage"){//用户发送信息处理varp=$("<p/>").html("  "+content);$("#divMessage").append(p);}}//关闭事件 socket.onclose= function(){console.log("socket已关闭");}//发生错误的事件 socket.onerror= function(){console.log("发生了错误");}});//发送消息 $("#btnSend").click(function(){if(document.getElementById("txtMessage").value=="" ||document.getElementById("txtMessage").value==null){alert("消息不能为空!");return;}socket.send(document.getElementById("txtMessage").value);document.getElementById("txtMessage").value= "";});//关闭事件 $("#btnClose").click(function(){socket.close();$("#btnConnection").prop("disabled",false);$("#btnClose").prop("disabled",true);$("#btnSend").prop("disabled",true);$("#spanUserName").text("已断开").prop("class","red");$("#txtUserName").prop("disabled",false);$("#txtUserName").prop("value","");$("#divMessage p").remove();$("#showAllUserName p:gt(0)").remove();});</script> </body> </html>
3、后台代码(WSServer.java):
packagesocket;import javax.websocket.*;importjavax.websocket.server.PathParam;importjavax.websocket.server.ServerEndpoint;importjava.io.IOException;import java.util.*;@ServerEndpoint("/ws/{user}")public classWSServer {privateString currentUser;private static Set<Session> map = new HashSet<>();//用户保存private static Map<String,String> userName = new HashMap<String, String>();//连接打开时执行 @OnOpenpublic void onOpen(@PathParam("user")String user, Session session){currentUser=user;map.add(session);userName.put(session.getId(),user);//自定义方法,更新客户端的客户在线信息 sendOutMessage();}//收到消息时执行 @OnMessagepublic void onMessage(String message,Session session) throwsIOException {//把信息传到已连接的用户客户端for(Session sess : map){//userMessage& 这段是为了客户端判断信息类型,是用户发送的消息,还是所有在线用户的信息sess.getBasicRemote().sendText("userMessage&"+currentUser + " : " +message);}}//连接关闭时执行 @OnClosepublic voidonClose(Session session, CloseReason closeReason){map.remove(session);//删掉断开连接的用户userName.remove(session.getId()); //删掉断开连接的用户信息//更新在线的所有用户 sendOutMessage();}//连接错误时执行 @OnErrorpublic voidOnError(Throwable t){t.printStackTrace();}private static voidsendOutMessage(){//将所有在线的用户拼接成字符串 userAllName& 这段是信息类型判断StringBuffer userAllStr = new StringBuffer("userAllName&");String str= "";for(String s : userName.keySet()){userAllStr.append(str+userName.get(s));str=",";}System.out.println(userAllStr);//循环所有客户id,向客户端发送信息for(Session session : map){try{session.getBasicRemote().sendText(userAllStr.toString());}catch(IOException e) {e.printStackTrace();}}}}
初心易得,始终难守。(LC)
介绍一个博客:http://best.cnblogs.com/
转载于:https://www.cnblogs.com/ldl326308/p/9456005.html
Java WebSocket实现简易聊天室相关推荐
- 基于Node.js + WebSocket 的简易聊天室
代码地址如下: http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.j ...
- java 聊天室开源_用java WebSocket做一个聊天室
最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了. 先看图: 实现了多客户机进行实时通讯. 下面看代码项目结 ...
- 原创 回归前端学习第21天-实现俄罗斯方块小游戏3(深入了解Websocket~优化简易聊天室)
对昨天的简易聊天室进行优化 增加一个mes对象,将传送的数据放在对象里 增加一个mes对象,将传送的数据放在对象里 wsServer.js中替换代码 broadcast(conn.nickname + ...
- java+websocket实现网页聊天室
核心技术websocket 前提 1.tocmat7.02版本以上 2.浏览器支持websocket通讯 3.这个是html5的功能 客户端和服务器建立连接 jsp/html页面 1.浏览器和后台服务 ...
- nodejs websocket 实现简易聊天室功能
文章目录 1. 服务端 app.js 代码 2. 客户端 app.html 代码 3. 样式代码 app.css 4. nodemon 辅助开发 首先说明,以下代码都是基于 Nodejs+webSoc ...
- Vue3 -- 基于Websocket实现简易聊天室
文章目录 标题 代码地址 表情包资源 chat.data.ts index.vue 标题 接上一篇博文 这里使用 Vue3 + Typescript + Websocket 实现在线聊天功能的前端部分 ...
- webSocket——Vue2简易聊天室
WebSocket原生实现 WebSocket-Vue2 WebSocket-Vue3 Vue2版本实现 前端实现 目录结构 login.vue 登录 <template><div& ...
- websocket实现简易聊天室
websocket支持全双工通信,也就是客户端和服务端双向通信.以前都是通过http轮询的方式实现实时的,这非常耗性能.Websocket不仅能节省资源和带宽,还能实现长链接的作用 前端通过创建Web ...
- Java WebSocket实现网络聊天室(群聊+私聊)
WebChat聊天室 2018.02.26 源码地址早就贴了呀, 留邮箱不如自己下载 项目地址: https://github.com/Amayadream/WebChat 2017.01.11更新 ...
最新文章
- 阿里专家讲中台:技术中台-分布式架构在蚂蚁金服的实践
- Flutter之第一个 Flutter App(四)
- libvirt(virsh命令介绍)
- 微信公众平台开发书籍推荐
- VTK:Snippets之RestoreSceneFromFieldData
- Python从N个数中找到最大的K个数
- SFTPUtils工具类及使用
- 基于Java学院网页的搜索引擎设计和实现
- light oj -1245 - Harmonic Number (II)
- 【DFS】LeetCode 17. Letter Combinations of a Phone Number
- 『题解』Codeforces446C DZY Loves Fibonacci Numbers
- VS2019 无法打开源文件“stdafx.h“ 问题
- 计算机二级vb基础教程,2017计算机二级考试内容VB
- openSetting:fail can only be invoked by user TAP gesture.
- 一、降维——机器学习笔记——降维(特征提取)
- 计算机数字媒体专业毕业论文,数字媒体艺术专业毕业论文
- 旗舰版ndows7bios设置,戴尔成铭 3988台式机装win7系统的方法(intel 9代BIOS设置方法和USB驱动)...
- 淘宝主图SKU图采集下载
- Dobbo微服务项目实战(详细介绍+案例源码) - 5.推荐好友列表/MongoDB集群/动态发布与查看
- 2020计算机保研之路:211上岸上海985
热门文章
- beetle.java 分析_使用beetle简单地实现高效的http基础服务
- 点序AS2258开卡方法,AS2258固态修复指导,AS2258量产工具开卡软件下载
- 嫦娥成功“打水漂”返回暴露了美国登月造假
- 电子信息类包括计算机软件吗,电子信息类包括什么专业
- 【敏捷CSM认证】Scrum Master
- Linux驱动分析——input输入子系统
- Web 上的隐形负担:视频编解码
- 计算机能换显卡吗,笔记本电脑换显卡,教您笔记本电脑怎么换显卡
- upload-labs靶场-pass-14
- SSL 链接安全协议的enum