vue+java websocket 实现单聊群聊

最近在研究vue,想写点案例,最后决定写一个比较常用的聊天室。再次记录一下,方便日后查阅。前端用vue构建,后端使用java websocket

关于websocket的好处这里不在赘述,直接贴代码

package webSocketDemo.web;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/wb")
public class socketWeb {
	
	   public static int Count = 0;
      public Session session;
	  public String name;
	   public static CopyOnWriteArraySet<socketWeb> listAll = new CopyOnWriteArraySet<socketWeb>();

	
	    @OnOpen 
	public  void    onOpen(Session session){
	       
	          Map<String, List<String>> map=	session.getRequestParameterMap();
	          if(map.size()>0){
	        	  List <String>list=map.get("name");
	        	  if(null!=list&&list.size()>0){
	        		     String name=list.get(0);
	        		     if(null!=name&&name.length()>0){
	        		    	       if(!haveName(name)){
	        		    	    	   this.name=name;
	        		    	    	   	this.session=session;
	        		    	    	   	listAll.add(this);
	        		    	          	Count++;
	        		    		       System.out.println("有客户端连接成功");
	        		    		       sendList( session);
	        		    	       }else{
	        		 
	        		    	    	   send(session,"sys_have");
	        		    	       }
	        		    	 
	        		     }
	        		  
	        	  }
	          }
	          System.out.println(map.get("name"));
	          System.out.println(map);
	       
	}
	    
	    
	    @OnClose
	    public void onClose(Session session){
	    	listAll.remove(this);
	    	Count--;
	    	   sendList( session);
	    	
	    }

	    @OnError
	    public void onError(Session session, Throwable error) {
	    	listAll.remove(this);
	    	Count--;
	    	   sendList( session);
	    }
	    
	    public static void  send(Session session, String msg){
	    	
			try {
				session.getBasicRemote().sendText(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}
	    	
	    }
	    
	    
	    @OnMessage
	    public void onMessage(String message,Session session){
	    	
	        System.out.println("有人骂你"+message); //####name####单挑
	    
	    		
	    		if(message.startsWith("##msg:")){
	    			String[] s=message.substring(6,message.length()-1).split(":");
	    			System.out.println("单聊");
	    			if(s.length>1){
	    				System.out.println(s[0]);
	    			 sendTo(s[0],"##msg:"+s[1]);
	    				System.out.println(s[1]);
	    			}
	    		}else if(message.startsWith("##msgall:")){
	    			System.out.println("群聊");
	    			broadcast(session,"##msg:"+message);
	    			
	    		}
		
	    }
	    
	    @OnMessage
	    public void onMessage(ByteBuffer message,Session session){
	    	
	        System.out.println("有人骂你"+message);
	    
	    	///	broadcast(session,message);
		
	    }
	    
	    public  static boolean  haveName(String name){
	    
	    		for(socketWeb sb: listAll){
	    			
	    			if(name.equals(sb.name)){
	    				
	    				return true;
	    			}
	    		}
			return false;
	    	
	    	
	    }
	    
	    
	    
	    
	    public static  List  getList(){
	    	List<String> list=new ArrayList<String>();
	    	  for (socketWeb item :listAll) {
	    		  
	    		       list.add(item.name);
	    		  
	    		  
	    	  }
	    	
	    	
	    	
			return list;
	    	
	    	
	    }
	    
	    
	    public static void sendList(Session session){
	    	List<String> list=getList();
	    	String str=String.valueOf(list);
	    	broadcastAll("##list:"+str);
	    	
	    }
	    public static void broadcast(Session session,String msg){
	        for (socketWeb item :listAll) {
	            try {
	                synchronized (item.session) {
	                    if (item.session!=session&&item.session.isOpen()) {
	                        item.session.getBasicRemote().sendText(msg);
	                        
	                    }
	                }
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    
	    
	    public static void broadcastAll(String msg){
	        for (socketWeb item :listAll) {
	            try {
	                synchronized (item.session) {
	                    if (item.session.isOpen()) {
	                        item.session.getBasicRemote().sendText(msg);
	                        
	                    }
	                }
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    
	    public static void sendTo(String name,String msg){
	        for (socketWeb item :listAll) {
	            try {
	            	if(item.name.equals(name)){
	                synchronized (item.session) {
	                    if (item.session.isOpen()) {
	                        item.session.getBasicRemote().sendText(msg);
	                    }
	                }
	            	}
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    
}

注意这里使用到了两个包:javax.websocket-api-1.0.jar  websocket必备 commons-io-1.4.jar    IO操作必备

 

关于前端的代码这里贴出核心部分

<template>
	
	
	
	<div>
		 <div class="stateInfo">
			  <input class="stateBt" type="text"  v-model="userName">
			  <input class="stateBt" type="button" value="连接"  @click="connect()">
			  <input class="stateBt" type="button" value="断开"  @click="close()">
			  <select class="stateBt" v-model="selectedItem"  placeholder="请选择对象" @change="changeObj($event)">
				  <option  v-for="p in userList" :key="p" >{{p}}</option>
			  </select>
		 </div>
		 
		 <div ref="cont" class="content">
			     <div class="pp"  v-for="(a,index) in msgs" :key="index" >
			       <div class="p1"  v-if="a.kind==1" >{{a.data}}</div>
				   <div class="p2"  v-else-if="a.kind==2">{{a.data}}</div>
			    </div>
		 </div>
		 
		 <div class="put">
			 <input   type="text" class="inputa" v-model="info" ><input  class="stateBt" type='button' value="发送" @click="send()">
		 </div>
	</div>
</template>

<script>
	
	export default {
		props:[
			'wz',
			'col'
			
		],
		name: "aa",
		data(){
			return {
				msgs:[{data:"我是模拟信息2",kind:1},{data:"我是模拟信息2",kind:1}],
			    socket:null,
				info:"hellow",
				userName:"userName",
				selectedItem:"all",
				userList:["all"]
			}
			
			
		},
		
		methods:{
			send:function(){
				if(null!=this.socket&&this.socket.readyState==1){
			          if(this.selectedItem=="all"){
							this.socket.send("##msgall:"+this.info);
							this.msgs.push({data:this.info,kind:2});
							this.$refs.cont.scrollTop = this.$refs.cont.scrollHeight
							 
					   }else{
							  this.socket.send("##msg:"+this.selectedItem+":"+this.info);
							  this.msgs.push({data:this.info,kind:2});
							  this.$refs.cont.scrollTop = this.$refs.cont.scrollHeight
								
						   
					   }
			
			
			}else{
				this.$notify({
				  title: '请先连接网络',
				  type: 'success',
				  message: '请先连接网络后在发送消息',
				  duration: 3000
				})
			}
			},
			connect:function(){
				var me=this;
				if(this.userName.length>0){
			this.socket=new WebSocket("ws://localhost:8080/webSocketDemo/wb?name="+this.userName);
					
				this.socket.onmessage=function(e){
					if(e.data.startsWith("##list:")){
						var strm=(e.data.substring(8,e.data.length-1)).split(",");
						console.log(strm);
						me.userList=["all"].concat(strm);
						
					}else if(e.data.startsWith("##msg:")){
						me.msgs.push({data:e.data,kind:1});
						me.$refs.cont.scrollTop = me.$refs.cont.scrollHeight
						
					}
					
			    	
				}		
			}else{
				this.$notify({
				  title: '请先输入用户名',
				  type: 'success',
				  message: '请先输入用户名,再连接',
				  duration: 3000
				})
				
			}
		  
         
			},
			close:function(){
				this.socket.close();
			},
			changeObj:function(obj){
				
				
			}
			
			
			
		},
		
		
		
		directives:{
		    // 注册一个局部的自定义指令 v-focus
		    oo:{
		      // 指令的定义
		      inserted: function (ea) {
		        // 聚焦元素
		        ea.focus();
			
				ea.style.background="orange";
		      }
		    }
		  }
		
		
		
		
	}
</script>

<style>
	*{
		margin: 0;
		padding: 0;
		border: 0;
	}
	.stateInfo{
		width:60%;
		height: auto;
		margin: 0 auto;
		background: peachpuff;
		border-radius: 5px;
		
	}
	.stateBt{
		width:80px;
		border-radius: 5px;
        background: mintcream;
		color:#008000;
			height:30px;
	}
	.content{
		width:60%;
		height:300px;
		background: papayawhip;
		overflow-y: scroll;
		margin: 0 auto;
		
	}
	.put{
		width:60%;
		height: auto;
		background: peachpuff;
		border-radius: 5px;
		margin: 0 auto;
	}
	.inputa{
		width:60%;
		height:30px;
		background:mintcream;
		border: 2px solid orange;
		border-radius: 5px;
	}
	.pp{
		width:100%;
		height:21px;
		
	}
	.p1{
		width:100%;
		height:21px;
		color:deeppink;
		text-align: left;
		font-size:28px;
		font-family: kaiti;
		margin: 10px;
		
	}
	.p2{
		width:100%;
		height:21px;
		color:green;
		text-align:right;
		font-size:28px;
		font-family: kaiti;
		
	}
	
	body{
		background: snow;
	}
	
</style>

当然这是初级版的,页面有点low,有需要的可以自己完善下。原码上传了,有需要可以点击下载

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值