利用websocket实现群聊以及单聊
利用websocket实现群聊以及单聊
- 项目结构
- 实现代码
- 运行截图
在这里提供一下思路,正常情况下我们登陆进去之后就应该打开一个ws连接,以便和服务器进行通信,将打开的管道用一个set容器进行存储,并将用户名或者其他能唯一标示用户的字段作为key,把与之对应的管道作为value存储到一个map集合中。
那么怎么实现广播的方法呢?其实很简单,这需要对set容器中的每一个管道进行遍历并执sendText()方法,就可以将消息传递给了集合中每个管道(前提是在每个用户进行登陆时将用户存储到一个集合中)。
接下来首先实现群聊,通过jquery获得输入框的内容,然后通过onmessage()方法向后端传递消息,在调用广播方法就可以实现群聊了。
接下来就是单聊,单聊的实现原理就是得到被单聊的人的用户名,然后在map集合中的得到与之对应的管道,然后调用sendText()方法就可以将消息发送给对应的人了。
话不多说,直接上图上代码
项目结构
实现代码
DemoConfig.java
import java.util.Set;import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;public class DemoConfig implements ServerApplicationConfig {@Overridepublic Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {// TODO Auto-generated method stubSystem.out.println("config................"+scan.size());//可以提供过滤作用return scan;}@Overridepublic Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {// TODO Auto-generated method stubreturn null;}}
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Insert title here</title>
</head>
<body>
<form action="LoginServlet">姓名:<input id="username" name="username" /><input type="submit" />
</form>
</body>
</html>
ChatRoom.jsp
<%@page import="java.io.PrintWriter"%>
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Insert title here</title><script type="text/javascript" src="jquery-1.4.2.min.js"></script><script type="text/javascript">var username="${sessionScope.username}";var ws;//一个ws对象就是一个管道var target="ws://localhost:8080/web_war_exploded/chatSocket?username="+username;window.onload=function(){//登录进入ChatRoom就打开socket通道if ('WebSocket' in window) {ws = new WebSocket(target);} else if ('MozWebSocket' in window) {ws = new MozWebSocket(target);} else {alert('WebSocket is not supported by this browser.');return;}ws.onmessage=function(event){eval("var msg="+event.data+";");if(undefined!=msg.welcome)$("#content").append(msg.welcome+"<br/>");if(undefined!=msg.usernames){$("#userList").html("");$(msg.usernames).each(function(){$("#userList").append("<input type=checkbox value='"+this+"'/>"+ this + "<br/>");});}if(undefined!=content){$("#content").append(msg.content+"<br/>");console.info(msg);}}}function subSend() {//判断是否选中var ss=$("#userList :checked");var val = $("#msg").val();console.info(ss.size());//如果未选中var obj=null;if(ss.size()==0){var obj={msg:val,type:1 //1广播 2单聊}}else {var to = $("#userList :checked").val();obj={to:to,msg:val,type:2 //1广播 2单聊}}var str = JSON.stringify(obj);/* $("msg").val("");var obj={to:to,msg:val,type:1 //1广播 2单聊} */ws.send(str);}</script>
</head>
<body>
<div id="container" style="border:1px solid black;width:400px;height:400px;float:left;"><div id="content" style="height:350px;"></div>
</div>
<div style="border-top:1px solid black;width:400px;height:50px;"><input id="msg" /><button onclick="subSend();">send</button>
</div><div id="userList" style="border:1px solid black;width:400px;height:400px;float:left;">
</div>
</body>
</html>
LoginServlet.java
package com.hys.servlet;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class LoginServlet*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public LoginServlet() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubrequest.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");String username = request.getParameter("username");request.getSession().setAttribute("username", username);/*System.out.println(username);*/response.sendRedirect("ChatRoom.jsp");}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}
ChatSocket.java
package com.hys.socket;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;import com.google.gson.Gson;
import com.hys.vo.ContentVo;
import com.hys.vo.Message;import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
@ServerEndpoint(value = "/chatSocket")
public class ChatSocket {
private String username;
private Session session;
private static Map<String, Session> map=new HashMap<String, Session>();/*将管道与用户名绑定*/
private static Set<ChatSocket> sockets=new HashSet<ChatSocket>();/*管道道的集合*/
private static List<String> names = new ArrayList<String>();/*用户的集合*/
private Gson gson = new Gson();@OnOpenpublic void open(Session session) {//当前的websocket的session不是之前的session//获取username//将当前的管道加入到管道的集合中去this.session = session;this.sockets.add(this);//将当前的username与session绑定String queryname = session.getQueryString();/*System.out.println(queryname);*/username=queryname.split("=")[1];this.names.add(username);this.map.put(this.username, this.session);/*System.out.println(username);*/String msg = "欢迎"+this.username+"进入聊天室";Message message=new Message();message.setWelcome(msg);message.setUsernames(this.names);this.broadcast(sockets,message.toJson());}@OnClosepublic void close(Session session) {this.sockets.remove(this);this.names.remove(this.username);String msg = this.username+"离开聊天室";Message message=new Message();message.setWelcome(msg);message.setUsernames(this.names);broadcast(sockets,message.toJson());}
// private static Gson gson=new Gson();@OnMessagepublic void onmessage(Session session,String json) {ContentVo vo=gson.fromJson(json, ContentVo.class);if(vo.getType()==1) {//广播Message message=new Message();message.setContent(this.username, vo.getMsg());this.broadcast(sockets,message.toJson());}else {//单聊//单聊过程与广播类似,/*分析前台传过来的消息的type如果是2的话就在map(存放的是key是用户名,value是socket)中通过getTo来取得接收信息的socket并通过to_session.getBasicRemote().sendText(gson.toJson(message))将消息传递给前台*//*举个不太恰当的例子,我想将一个苹果(消息)放到小明的冰箱(小明的前端页面),然后就我又不想动,我就想找小明然后我就喊小明的名字,小明(相当于服务器)听到我喊他的名字(从map集合中找到对应的session)然后小明就将苹果放入到了他的冰箱(对应的session调用sendText()方法传递消息)放到冰箱里(前台)* */String to=vo.getTo();Session to_session = this.map.get(to);System.out.println(to);System.out.println(to_session);Message message=new Message();message.setContent(this.username, vo.getMsg());try {to_session.getBasicRemote().sendText(gson.toJson(message));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//广播消息
public void broadcast(Set<ChatSocket>sockets ,String msg){//遍历当前所有的连接管道,将通知信息发送给每一个管道for(ChatSocket socket : sockets){try {//通过session发送信息socket.session.getBasicRemote().sendText(msg);} catch (IOException e) {e.printStackTrace();}}
}
}
ContentVo.java
package com.hys.vo;public class ContentVo {
private String to;
private String msg;
private Integer type;
public String getTo() {return to;
}
public void setTo(String to) {this.to = to;
}
public String getMsg() {return msg;
}
public void setMsg(String msg) {this.msg = msg;
}
public Integer getType() {return type;
}
public void setType(Integer type) {this.type = type;
}
}
Message.java
package com.hys.vo;import java.util.Date;
import java.util.List;import com.google.gson.Gson;public class Message {
private String welcome;
private List<String> usernames;
private String content;
public String getContent() {return content;
}
public void setContent(String content) {this.content = content;
}public void setContent(String name,String msg) {this.content = name+""+new Date().toLocaleString()+":<br/>"+msg+":<br/>";
}public String getWelcome() {return welcome;
}
public void setWelcome(String welcome) {this.welcome = welcome;
}
public List<String> getUsernames() {return usernames;
}
public void setUsernames(List<String> usernames) {this.usernames = usernames;
}
public String toJson() {return gson.toJson(this);
} public static Gson gson=new Gson();
}
运行截图
##注意
如果使用eclipse的话,可以建立相应的目录结构将代码粘贴进去,导入jar包即可
利用websocket实现群聊以及单聊相关推荐
- springboot+websocket构建在线聊天室(群聊+单聊)
系列导读: 1.springboot+websocket构建在线聊天室(群聊+单聊) 2.Spring Boot WebSocket:单聊(实现思路) 3.Websocket Stomp+Rabbit ...
- Android 融云单聊与群聊消息免打扰功能设置与消息删除功能实现
一.设置群聊与单聊消息免打扰功能: 1.下面直接进入逻辑代码: 实现监听事件: /*** 设置会话列表界面操作的监听器.*/RongIM.setConversationListBehaviorList ...
- websocket 群/单聊 基础
websocket 介绍 1.用户A 给 用户B 发送一条消息 问 用户B 多久可以收到 用户A 的消息电子邮件 - 可能是 一周期的时间 及时性很差传达室大爷 - 消息托付 及时性很差即时通讯 - ...
- (3)websocket实现单聊和群聊
1 资源下载地址 http://download.csdn.net/detail/jianfpeng241241/9325049 2 群聊图 2.1 zhangsan 发给所有人的图 2.2 发送 ...
- websocket 群聊和单聊实现简单在线客服
根据菜鸟教程上的解释: WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间 ...
- Springboot+netty+websocket 实现单聊群聊及用户鉴权
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.配置 二.Netty服务 1. WsServer构建 2. ChannelInitializer构建 3. 自定义 ...
- vue+websokect实现实时聊天,可单聊、可群聊(一)
效果图 效果网站链接,安全性不符合实际上线使用,仅供学习交流 https://livequeen.top 效果小程序二维码 (需现在web端获取账号) 思路 一个实时聊天功能 第一, ...
- Flask+geventwebsocket实现群聊与单聊功能
Flask+WebSocket 实现群聊与单聊功能 群聊 py文件 from flask import Flask ,request,render_template from geventwebsoc ...
- SpringBoot + Vue 实现基于 WebSocket 的聊天室(单聊)
前言 在前一篇文章SpringBoot 集成 STOMP 实现一对一聊天的两种方法中简单介绍了如何利用 STOMP 实现单聊,本文则将以一个比较完整的示例展示实际应用,不过本文并未使用 STOMP,而 ...
最新文章
- DOM和Diff算法你应该知道的那些事,快收藏!
- 【Java基础】Java中的持久属性集Properties
- Linux 临时表空间满了,Temporary表空间100%解决方案
- Leetcode--714. 买卖股票的最佳时间含手续费
- url中能出现的字符_网站URL配置4个技巧,轻松获得更多流量
- 利用matlab程序分别设计一正弦型信号_ARM Mbed数字信号处理
- mvp内粗泄露问题_如何在一小时内启动MVP服务器
- android的应用组件,跟我学android-Android应用基本组件介绍(五)
- STM32 编码器的CUBEMX的使用
- 初入c++ (八) c++输入和输出
- 跑赢业务的同时如何实现技术成长? | 凌云时刻
- 【转】el-cascade设置默认值遇到的坑!
- CHIL-SQL-LEFT JOIN 关键字
- 皮皮虾如何去水印视频
- 助教日志_沈航软件工程评分1.2班第三周作业及总评成绩
- 老男孩教育运维班100台规模集群全网数据备份项目上机实战
- 如何解决WORD安全模式错误问题
- c语言错误不允许使用不完整的类型,C语言不允许使用不完整的类型报错是什么意思啊...
- Firefox设置谷粉搜搜为默认搜索引擎的方法
- vue 列表展开收起