java WebSocket服务端与客户端实现,实现单推,群推

WebSocket 是独立的、创建在 TCP 上的协议。Websocket 通过HTTP/1.1 协议的101状态码进行握手。为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)。

    大家都知道客户端怎么去服务端去获取消息,http请求,webservice等等,都是主动由客户端去主动请求来的,怎么满足服务端去主动给客户端发消息。

 这就来说说WebSocket

       

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.zkb</groupId>
  <artifactId>WebSocket</artifactId>
  <version>0.0.1-SNAPSHOT</version>
      <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                     <encoding>${project.build.sourceEncoding}</encoding>
                    <compilerArguments>
                        <verbose />
                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar</bootclasspath>
                    </compilerArguments> 
                    <arguments>-Dhttps.protocols=TLSv1.2</arguments>                   
                </configuration>
            </plugin>
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                  <skip>true</skip>
                </configuration>
              </plugin>
        </plugins>
    </build>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

        <!-- 添加Servlet支持 -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>


        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- 增加fastjson-1.1.34.jar -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.34</version>
        </dependency>

        <!-- 转json -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.7</version>
        </dependency>
        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.4</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>

 

package com.zkb.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;
    }

}
package com.zkb;

import java.util.Set;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
/**
 * webSocket的核心配置类。
 * @author zkb
 */
public class ServerConfig implements ServerApplicationConfig {
    @Override
    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {
        return scan;
    }
    @Override
    public Set<ServerEndpointConfig> getEndpointConfigs(
            Set<Class<? extends Endpoint>> point) {
        return null;
    }

}
package com.zkb;

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.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.google.gson.Gson;
import com.zkb.vo.ContentVo;

/**
 * chatSocket Websocket连接入口,通道
 * @author zkb
 */
@ServerEndpoint("pms/chatSocket")
public class ChatSocket {

    private  static  Set<ChatSocket>  sockets=new HashSet<ChatSocket>();
    private  Session  session;
    private  static  Map<String, Session>  map=new HashMap<String, Session>();
    private  static  List<String>names=new ArrayList<String>();
    private String username;
    private Gson  gson=new Gson();

    /*
     * WebSocket打开连接
     */
    @OnOpen
    public void open(Session session){
        this.session = session;
        sockets.add(this);
        String queryString = session.getQueryString();
        this.username = queryString.substring(queryString.indexOf("=")+1);
        boolean bool = names.contains(this.username);     //判断这个客户端是否已经连接
        if(!bool){                                        //不存在就添加
       	 names.add(this.username);                        //发到在线客户端集合
       }else{
       	map.remove(this.username);                        //存在先移除以前这个客户端的session
       }
        map.put(this.username, this.session);
    }

    /*
     * 退出登录
     */
    @OnClose
    public void close(Session session){
        //移除退出登录客户端的通信管道
        sockets.remove(this);
        //将客户端从names中剔除
        names.remove(this.username);
    }

    /*
     * 接收客户端发送过来的消息,然后判断是广播还是单聊
     */
    @OnMessage
    public void receive(Session  session,String msg) throws IOException{
        //将客户端消息转成json对象
        ContentVo vo = gson.fromJson(msg, ContentVo.class);
        //如果是群播,就像消息广播给所有人
        if(vo.getType()==1){
            broadcast(sockets, vo.getMsg());
        }else{//如果是单推,就针对人来推
            //根据单聊对象的名称拿到要单聊对象的Session
            Session to_session = map.get(vo.getTo());
            //如果是单聊,就将消息发送给对方
            to_session.getBasicRemote().sendText(vo.getMsg());
        }
    }

    /*
     * 广播消息
     */
    public void broadcast(Set<ChatSocket>sockets ,String msg){
        //遍历当前所有的连接管道,将通知信息发送给每一个管道
        for(ChatSocket socket : sockets){
            try {
                //通过session发送信息
                socket.session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

package ywgz_bzb_pms;



import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.channels.NotYetConnectedException;

import org.java_websocket.WebSocket.READYSTATE;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.handshake.ServerHandshake;

public class Client {

	public static WebSocketClient client;

	public static void main(String[] args) throws URISyntaxException, NotYetConnectedException, UnsupportedEncodingException, InterruptedException {
	    client = new WebSocketClient(new URI("ws://127.0.0.1:8080/WebSocket/pms/chatSocket?username=113195"),new Draft_17()) {

	        @Override
	        public void onOpen(ServerHandshake arg0) {
	            System.out.println("打开链接");
	        }

	        @Override
	        public void onMessage(String arg0) {
	            System.out.println("收到消息:"+arg0);
	        }

	        @Override
	        public void onError(Exception arg0) {
	            arg0.printStackTrace();
	            System.out.println("发生错误已关闭");
	        }

	        @Override
	        public void onClose(int arg0, String arg1, boolean arg2) {
	            System.out.println("链接已关闭");
	        }

	        @Override
	        public void onMessage(ByteBuffer bytes) {
	            try {
	                System.out.println(new String(bytes.array(),"utf-8"));
	            } catch (UnsupportedEncodingException e) {
	                e.printStackTrace();
	            }
	        }


	    };

	    client.connect();

	    while(!client.getReadyState().equals(READYSTATE.OPEN)){
	        System.out.println("还没有打开");
	        Thread.sleep(500);
	    }
	    System.out.println("打开了");
	    client.send("{msg:\"999999999999999999\",type:\"1\"}");                  //群推
//	    client.send("{to:\"789789\",msg:\"999999999999999999\",type:\"2\"}");    //     type   1是群推    2是单推   为2的时候 必须有 to  给谁推
	}

}

 

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斗码士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值