一、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: 华文琥珀;">&emsp;在线用户:</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("&nbsp;"+userNames[i]));}}else if(sign=="userMessage"){//用户发送信息处理varp=$("<p/>").html("&emsp;&emsp;"+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实现简易聊天室相关推荐

  1. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下: http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.j ...

  2. java 聊天室开源_用java WebSocket做一个聊天室

    最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了. 先看图: 实现了多客户机进行实时通讯. 下面看代码项目结 ...

  3. 原创 回归前端学习第21天-实现俄罗斯方块小游戏3(深入了解Websocket~优化简易聊天室)

    对昨天的简易聊天室进行优化 增加一个mes对象,将传送的数据放在对象里 增加一个mes对象,将传送的数据放在对象里 wsServer.js中替换代码 broadcast(conn.nickname + ...

  4. java+websocket实现网页聊天室

    核心技术websocket 前提 1.tocmat7.02版本以上 2.浏览器支持websocket通讯 3.这个是html5的功能 客户端和服务器建立连接 jsp/html页面 1.浏览器和后台服务 ...

  5. nodejs websocket 实现简易聊天室功能

    文章目录 1. 服务端 app.js 代码 2. 客户端 app.html 代码 3. 样式代码 app.css 4. nodemon 辅助开发 首先说明,以下代码都是基于 Nodejs+webSoc ...

  6. Vue3 -- 基于Websocket实现简易聊天室

    文章目录 标题 代码地址 表情包资源 chat.data.ts index.vue 标题 接上一篇博文 这里使用 Vue3 + Typescript + Websocket 实现在线聊天功能的前端部分 ...

  7. webSocket——Vue2简易聊天室

    WebSocket原生实现 WebSocket-Vue2 WebSocket-Vue3 Vue2版本实现 前端实现 目录结构 login.vue 登录 <template><div& ...

  8. websocket实现简易聊天室

    websocket支持全双工通信,也就是客户端和服务端双向通信.以前都是通过http轮询的方式实现实时的,这非常耗性能.Websocket不仅能节省资源和带宽,还能实现长链接的作用 前端通过创建Web ...

  9. Java WebSocket实现网络聊天室(群聊+私聊)

    WebChat聊天室 2018.02.26 源码地址早就贴了呀, 留邮箱不如自己下载 项目地址: https://github.com/Amayadream/WebChat 2017.01.11更新 ...

最新文章

  1. 阿里专家讲中台:技术中台-分布式架构在蚂蚁金服的实践
  2. Flutter之第一个 Flutter App(四)
  3. libvirt(virsh命令介绍)
  4. 微信公众平台开发书籍推荐
  5. VTK:Snippets之RestoreSceneFromFieldData
  6. Python从N个数中找到最大的K个数
  7. SFTPUtils工具类及使用
  8. 基于Java学院网页的搜索引擎设计和实现
  9. light oj -1245 - Harmonic Number (II)
  10. 【DFS】LeetCode 17. Letter Combinations of a Phone Number
  11. 『题解』Codeforces446C DZY Loves Fibonacci Numbers
  12. VS2019 无法打开源文件“stdafx.h“ 问题
  13. 计算机二级vb基础教程,2017计算机二级考试内容VB
  14. openSetting:fail can only be invoked by user TAP gesture.
  15. 一、降维——机器学习笔记——降维(特征提取)
  16. 计算机数字媒体专业毕业论文,数字媒体艺术专业毕业论文
  17. 旗舰版ndows7bios设置,戴尔成铭 3988台式机装win7系统的方法(intel 9代BIOS设置方法和USB驱动)...
  18. 淘宝主图SKU图采集下载
  19. Dobbo微服务项目实战(详细介绍+案例源码) - 5.推荐好友列表/MongoDB集群/动态发布与查看
  20. 2020计算机保研之路:211上岸上海985

热门文章

  1. beetle.java 分析_使用beetle简单地实现高效的http基础服务
  2. 点序AS2258开卡方法,AS2258固态修复指导,AS2258量产工具开卡软件下载
  3. 嫦娥成功“打水漂”返回暴露了美国登月造假
  4. 电子信息类包括计算机软件吗,电子信息类包括什么专业
  5. 【敏捷CSM认证】Scrum Master
  6. Linux驱动分析——input输入子系统
  7. Web 上的隐形负担:视频编解码
  8. 计算机能换显卡吗,笔记本电脑换显卡,教您笔记本电脑怎么换显卡
  9. upload-labs靶场-pass-14
  10. SSL 链接安全协议的enum