其他分享
首页 > 其他分享> > 利用websocket实现群聊以及单聊

利用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 {

	@Override
	public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {
		// TODO Auto-generated method stub
		System.out.println("config................"+scan.size());
		//可以提供过滤作用
		return scan;
	}

	@Override
	public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {
		// TODO Auto-generated method stub
		return 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 stub
		request.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 stub
		doGet(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();
    @OnOpen
	public 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());
	}
    
    
    
    @OnClose
    public 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();
    @OnMessage
    public 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 block
				e.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包即可

标签:username,websocket,String,群聊,session,单聊,msg,import,public
来源: https://blog.csdn.net/qq_37793966/article/details/90522037