介绍
websocket我这文章就不介绍了,具体意思百度查下,很简单。
我就一句话介绍下,实时通信的!
项目
我把我这个简易版聊天平台源码开源发在这篇文章里面。
用法,以及每个模块的功能都说尽量的说详细点。
源码
maven
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier> <!-- 就是这句 -->
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<scope>compile</scope>
</dependency>
Java代码
import net.sf.json.JSONObject;
import sun.security.krb5.internal.HostAddress;
import sun.security.rsa.RSASignature;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ServerEndpoint("/websock/{name}")
public class WebSocket {
//name用于记录当前的websoket是谁
private String name;
//链接,用于记录当前的链接
private Session session;
private static Map<String,WebSocket> AllClients= new HashMap<>();
public static List<String> haoyou=new ArrayList<>();
//打开链接
@OnOpen
public void onOpen(@PathParam("name") String name, Session session){
this.name=name;
this.session=session;
AllClients.put(name,this);
System.out.println("建立链接");
haoyou.add(name);
}
//处理消息
@OnMessage
public void OnMessage(Session session,String message){
JSONObject jsonobject=JSONObject.fromObject(message);
int flag= Integer.parseInt(jsonobject.getString("flag"));
int Radiovalue= Integer.parseInt(jsonobject.getString("Radiovalue"));
System.out.println("flag="+flag+"Radiovalue="+Radiovalue);
if(flag==0&&Radiovalue==88888){
//好友上线功能
HaoYou(session,message);
}else if(flag==1&&Radiovalue!=88888){
if(Radiovalue==1){
//发消息模块(私聊)
SendXiaoXi(session,message);
}else {
//群发消息
SendXiaoXiAll(session,message);
}
}
else{
System.out.println("未知识别码");
}
}
public void SendXiaoXiAll(Session session,String message){
System.out.println("当前为群聊模式");
JSONObject jsonobject=JSONObject.fromObject(message);
String toMessage= jsonobject.getString("toMessage");
String username=jsonobject.getString("username");
//原理找到每个用户的名字
//WebSocket socket=AllClients.get(to);
//Session tosession=socket.getSession();
WebSocket socket=null;
Session tosession=null;
System.out.println("当前在线好友"+haoyou.size());
for(int i = 0 ; i < haoyou.size() ; i++) {
//System.out.println(haoyou.get(i));
if(!haoyou.get(i).equals(username)){
socket=AllClients.get(haoyou.get(i));
tosession=socket.getSession();
if(tosession.isOpen()){
tosession.getAsyncRemote().sendText(username+"群发了一个为消息:"+toMessage);
session.getAsyncRemote().sendText("给群发消息:"+toMessage);
}
}
}
}
public void HaoYou(Session session,String message){
JSONObject jsonobject=JSONObject.fromObject(message);
//当前用户的名字(需要排除当前名字)
String username=jsonobject.getString("username");
System.out.println("当前在线-->"+username);
System.out.println("当前在线人数"+ haoyou.size());
String str_haoyou="";
if(haoyou.size()==1){
session.getAsyncRemote().sendText("当前无人在线,欢迎使用");
}else{
for(int i = 0 ; i < haoyou.size() ; i++) {
//System.out.println(haoyou.get(i));
if(!haoyou.get(i).equals(username)){
str_haoyou=str_haoyou+haoyou.get(i)+" ";
}
}
System.out.println("好友上线列表为"+str_haoyou);
session.getAsyncRemote().sendText("当前你的好友"+str_haoyou+"在线");
}
}
public void SendXiaoXi(Session session,String message){
System.out.println("当前为私聊模式");
JSONObject jsonobject=JSONObject.fromObject(message);
String to=jsonobject.getString("toUer");
String toMessage= jsonobject.getString("toMessage");
//目标接收者的wevsocket
WebSocket socket=AllClients.get(to);
//通过session发送消息
if(socket!=null){
Session tosession=socket.getSession();
if(tosession.isOpen()){
//找到链接的另外一端
String username= jsonobject.getString("username");
tosession.getAsyncRemote().sendText(username+"给你发消息:"+toMessage);
session.getAsyncRemote().sendText("给"+to+"发消息:"+toMessage);
}
}else{
//正常来说要缓存消息
session.getAsyncRemote().sendText("对方不在线");
}
}
@OnError
public void OnError(Session session,Throwable e){
}
@OnClose
public void OnClose(Session session){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public static Map<String, WebSocket> getAllClients() {
return AllClients;
}
public static void setAllClients(Map<String, WebSocket> allClients) {
AllClients = allClients;
}
}
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>好友聊天 1.0</title>
<script type="text/javascript">
var websocket=null;
var Radiovalue=1;
function connection(){
var username=document.getElementById("username").value;
if("WebSocket" in window){
//当前浏览器支持不支持websoket
websocket=new WebSocket("ws://"+document.location.host+"/websock/"+username);
}else{
alert("什么破电脑");
}
websocket.onopen=function (){
console.log("username--->"+username);
document.getElementById("message").innerHTML="建立链接了";
var message='{"toUer":"'+""+'","toMessage":"'+""+'","username":"'+username+'","flag":"'+0+'","Radiovalue":"'+88888+'"}';
websocket.send(message);
}
websocket.onmessage=function (event){
var data=event.data;
document.getElementById("message").innerHTML=data;
}
websocket.onerror=function (){
document.getElementById("message").innerHTML="出现异常了";
}
websocket.onclose=function (){
document.getElementById("message").innerHTML="链接关闭了";
}
window.onbeforeunload=function (){
//监听窗口的关闭
if(webSoket!=null){
webSoket.close();
}
}
}
function sendMessage(){
//获取发送给谁
//获取发送内容
var toUser=document.getElementById("toUser").value;
var toMessgae=document.getElementById("toMessgae").value;
var username=document.getElementById("username").value;
if(websocket!=null){
var message='{"toUer":"'+toUser+'","toMessage":"'+toMessgae+'","username":"'+username+'","flag":"'+1+'","Radiovalue":"'+Radiovalue+'"}';
websocket.send(message);
}
}
function RadioOnclick(value){
Radiovalue=value;
console.log("勾选为-->"+Radiovalue);
}
</script>
</head>
<body>
<input id="username" name="context" type="text"><button onclick="connection()">链接</button><br>
接收者名字:<input type="text" id="toUser" name="toUser"><br>
内容: <input type="text" id="toMessgae" name="toMessgae"><br>
<input type="radio" checked="true" name="storeLocation" value="1" onclick="RadioOnclick(this.value)" >私聊
<input type="radio" name="storeLocation" value="2" onclick="RadioOnclick(this.value)">群发
<input type="hidden" id="storeLocation" value=""/>
<br><br>
<button onclick="sendMessage()">发送</button><br><br><br><br><br><br>
<span style="color: red">提示消息:</span><span id="message"> </span>
</body>
</html>
介绍
源码上面很清楚,如果maven不全,那就自行百度查下需要了自己粘贴找一个就行了。主要是我想介绍下这里面的重点。
- 第一点我要说的很简单,你要使用这个还是去百度查下这玩意是干啥的,其实我理解为就是双向通信用的。
- 这个里面前端里面也有几个方法,我源码里面也写到了。onopen:用于指定连接成功后的回调函数;onmessage:用于指定当从服务器接受到信息时的回调函数;onclose:用于指定连接关闭后的回调函数;onerror:用于指定连接失败后的回调函数; 我个人感觉这几个最为重要,其他可以了解了解就欧克了
- 连接呢,前端new WebSocket("ws://"+document.location.host+"/websock/"+username);后端@ServerEndpoint("/websock/{name}");这样即可以,也就是意思必须保持一样的,要不然匹配不上,就会连不上。
- 必须配置上面那个通信通道,要不然没有用的
- 发消息呢,也就是我源码中sendMessage()函数中,websocket.send(message);也就是用上面所提到的websocket对象调用send函数即可,如果你配置没有问题的话,此时此刻你调用了那便把数据发送到后端去了。后端接收的方法等哈下面会提到。这里利用的json格式字符串传入的,后端怎么接收我也会说到
- 第三点呢,算是补充,大家可以在各个方法里面增加对应的功能,可扩展类型的,比如我写了连接成功会有一个好友上线功能。你可以在用户退出增加一个好友下线功能等等。
- 待补充。。。。
后端介绍就有点多了
好友上线功能
利用OnOpen这个方法来判断那些好友上线了,我做了对应的处理。使用了一个list集合,因为只是统计用户名字,所以用list接口很简单。写法有很多种。
功能实现过程:在连接的时候存入对应的名字到list集合,如果现在有第二人上线了,把list集合直接遍历下即可,但是切记一定要把第二人用户名除去。然后把list集合对应的结果放入到字符串里面即可,你可以也做出对应的处理。我这里没有做。
整理好字符串利用这个session.getAsyncRemote().sendText("当前无人在线,欢迎使用");这个意思就是把此消息,返回到当前用户的页面端。也就是这个消息是本人看的。还有一个是发送到对方的,我没有在源码里面的,下面会提到。
私聊功能
利用OnMessage这个函数来接收消息等前端发送过来的东西。我这里先解析json字符串,然后提取到对应的用户账号和消息字符串。提取到对应的用户名字,然后去存放的map集合里面查找对应的session是否存在(肯定是存在的),我知道存在,但是必须找到对应的,因为给对方发消息,必须要用对方的session,找到之后,我还是做的看对方的session是否存活,要不然就判断对方不在线,要不然在发送,发送也相当的简单tosession.getAsyncRemote().sendText(username+"群发了一个为消息:"+toMessage);用对方的sesson发送即可。
群聊模式
私聊模式懂了,群聊更简单,无非就是要把在线的用户,每个session都要拿到,然后在发送。
这里重点要说的就是,必须排除本用户,也就是那个要用要发群消息,那就把那个用户排除,然后利用剩下用户的session给他们发消息即可,代码也写到了
群聊和私聊代码有点类似,无非就是稍微有所改动。
总结
这次吸收不错,这篇文章我也写了快1个消息,尽可能的希望大家都可以简单的上手,里面有很多功能没有扩展,因为我要去补作业,马上期末了,后面功能在说吧,源码上面也发了,可以自己玩玩,运行截图就不放出来了。
文章全部是本人原创,请勿转发,谢谢配合,版权所有-南香香-你会喜欢我吗
牛
哈哈哈哈哈哈