基于Java和websocket的在线聊天程序(可群发和选择用户)
来源:互联网 发布:网络十大公会 编辑:程序博客网 时间:2024/05/21 08:38
最近在开发程序过程中需要用到服务器端推送,查阅资料主要有三种方式:
第一是使用ajax长轮询;
第二是使用cmet4j;
第三是使用websocket。
关于这三种方式,websocket优点明显,主要包括:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws
(如果加密,则为wss
),服务器网址就是 URL。
websocket的介绍网上有很多,用websocket实现的聊天室也很多,但功能都不完善(也许是我没看懂别人的代码),而且也不容易看懂。对于没有接触过这的来说,因为很多基础概念没弄懂,比如远程端点,websocket的session等。关于websocket有本教材——Java.WebSocket.Programming,国内翻译的感觉不怎么样,简单了解看前面四章就够了,下面是教材:http://www.java1234.com/a/javabook/javabase/2016/0605/6215.html
websocket需要websocket-api.jar这个包,这个包tomcat已经自带,因此不用手动将这个包导入自己的项目;传输数据使用JSON的jar包(6个)需要添加到自己的项目中。
一、服务器代码
package com;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import net.sf.json.*; import javax.websocket.*;import javax.websocket.server.*;@ServerEndpoint(value = "/chat")public class EndPoint{//远程endPoint,使用userName作为Key进行绑定private static ConcurrentMap<String,EndPoint>clientSet = new ConcurrentHashMap<>(); //连接时,获得用户名private String user;//_websocket会话private Session session;@OnOpenpublic void start(Session session){this.session = session;user=this.session.getRequestParameterMap().get("user").get(0);clientSet.put(user, this);List<String>list =new ArrayList<>( clientSet.keySet()); broadcast(list); Message msg=new Message("server","All",String.format("【%s %s】",user, "加入了聊天室!"));sendMessage(msg);}// 当端断开连接时自动激发该方法@OnClosepublic void end(){clientSet.remove(user);Message msg=new Message("server","All",String.format("【%s %s】",user, "离开了聊天室!"));sendMessage(msg);List<String>list =new ArrayList<>( clientSet.keySet()); broadcast(list);}// 每当收到客户端消息时自动激发该方法@OnMessagepublic void onMessage(String message){JSONObject json = JSONObject.fromObject(message); Message msg = (Message)JSONObject.toBean(json,Message.class);sendMessage(msg);}// 当客户端通信出现错误时,激发该方法@OnErrorpublic void onError(Throwable t) throws Throwable{System.out.println("WebSocket服务端错误 " + t);}// 发送消息private static void sendMessage(Message msg){//如果为all,遍历历用户列表,逐个发送,否则只发送给一个if(msg.getTo().equals("All")){Set<String>clientKey = clientSet.keySet(); for(String k: clientKey){ EndPoint client=clientSet.get(k); try{synchronized (client){// 发送消息client.session.getBasicRemote().sendText(JSONObject.fromObject(msg).toString());}}catch (IOException e){clientSet.remove(k);try{client.session.close();}catch (IOException e1){}Message msgError=new Message("server","All",String.format("【%s %s】",k, "已经被断开了连接。"));sendMessage(msgError);List<String>list =new ArrayList<>( clientSet.keySet()); broadcast(list);} } }else{ EndPoint client=clientSet.get(msg.getTo()); try{synchronized (client){// 发送消息client.session.getBasicRemote().sendText(JSONObject.fromObject(msg).toString());}}catch (IOException e){clientSet.remove(msg.getTo());try{client.session.close();}catch (IOException e1){}Message msgError=new Message("server","All",String.format("【%s %s】",msg.getTo(), "已经被断开了连接。"));sendMessage(msgError);List<String>list =new ArrayList<>( clientSet.keySet()); broadcast(list);} EndPoint clientSend=clientSet.get(msg.getFrom()); try{synchronized (clientSend){// 发送消息clientSend.session.getBasicRemote().sendText(JSONObject.fromObject(msg).toString());}}catch (IOException e){} }}// 广播用户列表消息,客户端更新private static void broadcast(List<String> list){ for(String k: list){ try{synchronized (k){// 发送消息clientSet.get(k).session.getBasicRemote().sendText(JSONArray.fromObject(list).toString());}} catch (IOException e){System.out.println("聊天错误,向客户端 "+ k + " 发送消息出现错误。");clientSet.remove(k);try{clientSet.get(k).session.close();}catch (IOException e1){}Message msgError=new Message("server","All",String.format("【%s %s】",k, "已经被断开了连接。"));sendMessage(msgError);} }}}
二、客户端代码
<!DOCTYPE html><html><head><meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>WebSocket聊天室 </title><style>.height{height:6px;}</style><script type="text/javascript">//创建客户端使用的用户名var userName;var websocket=null;//穿件websocket函数function ws(){userName=document.getElementById('user').value;webSocket = new WebSocket("ws://"+location.host+"/MySocket/chat?user="+userName);// 为onmessage事件绑定监听器,接收消息webSocket.onmessage= function(event){//分析json,如果没有to则是用户列表,否则为普通消息var json = JSON.parse(event.data);if((typeof json.to) == 'undefined'){var html='<option>All</option>';for(var user in json){html+='<option>'+json[user]+'</option>';}document.getElementById('select').innerHTML = html;}else{var show = document.getElementById('show');//判断json,如果发送者为自己,则显示在右侧if(json.from==userName){show.innerHTML+= '<p class="height" align="right">'+json.msg +":"+json.from +'</p>';}else{show.innerHTML+='<p class="height" >'+json.from+":"+json.msg +'</p>';}show.scrollTop = show.scrollHeight;}}webSocket.onclose = function (){Console.log('WebSocket已经被关闭。');};}//发送消息function sendMsg(){var inputMsg = document.getElementById('msg');var selectTo=document.getElementById('select');//普通消息格式var msg={from:userName,to:selectTo.value,msg:inputMsg.value}// 发送消息webSocket.send(JSON.stringify(msg));// 清空单行文本框inputMsg.value = "";}</script></head><body><div style="width:600px;height:50px;"><input type="text" size="80" id="user" name="user" placeholder="输入姓名"/><input type="button" value="链接" id="coon" onclick="ws()"/></div><div style="width:600px;height:240px;overflow-y:auto;border:1px solid #333;" id="show"></div><select id="select"></select><input type="text" size="80" id="msg" placeholder="输入聊天内容"/><input type="button" value="发送" id="sendBn" onclick="sendMsg()"/></body></html>
三、最终效果
需要项目文件的可以在我的主页下载。。。
- 基于Java和websocket的在线聊天程序(可群发和选择用户)
- java WebSocket实现简单的聊天室(包括群发和点对点聊天)
- 基于Tomcate、java、websocket 简单在线聊天
- java 网站用户在线和客服聊天
- 基于WebSocket的即时聊天程序
- 基于Java socket和多线程的简易聊天小程序
- 基于C# Winform的简易聊天程序[socket-信息群发]
- 基于websocket+java聊天系统的实现
- 基于webSocket实现的一对一在线聊天系统
- 基于Html5 websocket和Python的在线聊天室
- 基于Html5 websocket和Python的在线聊天室
- java 基于servlet+maven+mybatis+websocket聊天,包括单聊和群聊
- 基于html5 localStorage , web SQL, websocket的简单聊天程序
- 基于WebSocket的聊天系统
- 基于Struts2和hibernate的WebSocket聊天室的实现教程五:聊天机制
- 简易Java web在线聊天-websocket
- 基于WebSocket实现的Android和H5聊天通讯实例【附效果图附所有源码】
- Spring 学习——基于Spring WebSocket 和STOMP实现简单的聊天功能
- 算法总结JS版(一)—— 冒泡排序(Bubble Sort)
- 用C实现C编译器(一)
- Filter(第四节)
- Junit单元测试避免死循环
- 深入Struts2学习(三)
- 基于Java和websocket的在线聊天程序(可群发和选择用户)
- Binary Search:34. Search for a Range
- C语言中的宏
- 数组中的strlen和sizeof
- GIT的安装及上传代码到码云
- 白话解析:一致性哈希算法 consistent hashing
- 本文作者YY硕,来自大疆工程师《机器人工程师学习计划》
- 从零开始学电脑 3.1
- laravel中多个DB连接--读写分离