首先WebSocket打破了传统的web请求响应模式,实现管道式的实时通信,并且可以持续连接。

相对于传统 HTTP 每次请求-应答都需要客户端与服务端建立连接的模式,WebSocket 是类似 Socket 的 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

所需jar包:websocket-api.jar,tomcat从7.0版本开始支持WebSocket,并且已经包含了所需jar包

websocket在tomcat中的参考配置文件路径:

webapps\examples\WEB-INF\classes\websocket

webapps\examples\websocket

首先我们需要一个class去实现ServerApplicationConfig接口作为配置文件,此时必须重写两个方法,分别是getEndpointConfigs()、getAnnotatedEndpointClasses(),getEndPointConfigs 获取所有以接口方式配置的webSocket类,getAnnotatedEndpointClasses 扫描src下所有用@ServerEndPoint注解的类。通常我们使用注解扫描的方法去实现,毕竟方便吧,该方法需要传入一个一class作为元素的Set集合,该集合表示扫描到的类,并且返回这个Set集合

package com.asen.websocket.config;

import java.util.HashSet;
import java.util.Set; import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig; public class WebSocketConfig implements ServerApplicationConfig{ @Override
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) { Set<Class<?>> results = new HashSet<Class<?>>(); for (Class<?> clazz : scanned) {
if (clazz.getPackage().getName().startsWith("com.asen.websocket.")) {
results.add(clazz);
}
} return results;
} @Override
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {
// TODO Auto-generated method stub
return null;
} }

此时我们需要一个类并添加@ServerEndpoint("/chat")注解,此时表示的请求路径为ws://IP地址:8080/工程名称/chat,注意这里用的是ws协议,并不是传统的http,在这里类中通常用到三个注解:@OnOpen这个注解下的类会在客户端发起请求的时候执行,@OnMessage注解下的类通常是在接收客户端发送数据到服务器的时候执行,@OnClose注解下的类通常是在客户端断开连接的时候执行。

常用的Api:

获取服务器发送的请求参数session.getQueryString();

向客户端发送数据session.getBasicRemote().sendText(msg);

package com.asen.websocket.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
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.asen.websocket.entity.User;
import com.google.gson.Gson; @ServerEndpoint("/chat")
public class SocketService { private Session session;
private static String username;
private static Set<SocketService> connections = new HashSet<SocketService>();
private static List<String> usernames = new ArrayList<String>(); /*
* websocket并不是单例的,每增加一名用户使用系统,就会创建一个websocket实例,
* 所以session这个全局变量有多份,不能用static修饰,
* 而广播消息的时候是根据session来判断发给谁的------------s.session.getBasicRemote().sendText(msg);
* 如果session用static修饰,那么消息只会发送给同一个人,并且当前系统有多少个用户,就会收到多少份相同的消息
*/
public SocketService(){
System.out.println("创建了SocketServcie()实例");
} @OnOpen
public void connected(Session session) {
this.session = session;
connections.add(this); //获取服务器发送的请求参数
String str = session.getQueryString(); this.username = str.substring(str.indexOf("=") + 1); System.out.println(username + "开始使用本系统" + ", " + "sessionId为:" + session.getId()); usernames.add(username); User user = new User(); user.setNames(usernames); Gson gson = new Gson(); broadcast(connections, gson.toJson(user));
} /*
*服务器通过参数msg接收客户端发送过来的数据
*/
@OnMessage
public void getMsg(Session session, String msg) { User user = new User();
user.setDate(new Date().toLocaleString());
user.setFrom(this.username);
user.setSendMsg(msg); Gson gson = new Gson(); broadcast(connections, gson.toJson(user));
} @OnClose
public void close(Session session){
connections.remove(this);
usernames.remove(this.username); User user = new User(); user.setNames(usernames); Gson gson = new Gson(); broadcast(connections, gson.toJson(user));
} //广播消息
public static void broadcast(Set<SocketService> sockets, String msg){
for (SocketService s : sockets){
try {
//向客户端发送数据
s.session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

WebSocket浅析(一):实现群聊功能的更多相关文章

  1. Java-->实现群聊功能(C/S模式--TCP协议)

    --> Java 对TCP协议的支持: --> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端. -- ...

  2. day04-1群聊功能

    多用户即时通讯系统04 4.编码实现03 4.5功能实现-群聊功能实现 4.5.1思路分析 群聊的实现思路和私聊的实现非常类似. 不同的是:私聊时,服务端接收到消息后,只需要找出接收方的socket并 ...

  3. Websocket 群聊功能

    websocket 群聊 前提关闭防火墙 写入代码 from flask import Flask,request,render_template from geventwebsocket.handl ...

  4. WebSocket刨根问底(三)之群聊

    前两篇文章[WebSocket刨根问底(一)][WebSocket刨根问底(二)]我们介绍了WebSocket的一些基本理论,以及一个简单的案例,那么今天继续,我们来看一个简单的群聊的案例,来进一步了 ...

  5. WebSocket+Java 私聊、群聊实例

    前言 之前写毕业设计的时候就想加上聊天系统,当时已经用ajax长轮询实现了一个(还不懂什么是轮询机制的,猛戳这里:https://www.cnblogs.com/hoojo/p/longPolling ...

  6. Asp.net SignalR 应用并实现群聊功能 开源代码

    ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...

  7. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能

    休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...

  8. netty实现群聊功能

    [概述] 实现一个网络群聊工具.参与聊天的客户端消息是通过服务端进行广播的. 主要由两块组成:聊天服务器端(ChatServer)和聊天客户端(ChatClient). 聊天服务器(ChatServe ...

  9. java项目-----客户端与客户端通信--实现群聊功能的代码

    这是这个网络聊天室项目的原理图: 很简单,首先ABCD是4个客户端,当A发送信息给服务器,服务器实现以广播的形式把信息全发给每个人---群发群聊 客户端代码: package com.aa; impo ...

  10. netty无缝切换rabbitmq、activemq、rocketmq实现聊天室单聊、群聊功能

    netty的pipeline处理链上的handler:需要IdleStateHandler心跳检测channel是否有效,以及处理登录认证的UserAuthHandler和消息处理MessageHan ...

随机推荐

  1. 安卓弹出对话框——Alertdialog(一)

    首先看各种样式的对话框: 我们看到,Dialog有很多的子类实现,所以我们要定义一个对话框,使用其子类来实例化一个即可,而不要直接使用Dialog这个父类来构造. 二.AlertDialog 今天我们 ...

  2. Struts2验证

    一.声明式验证 1.字段验证 fielderror的两种显示方式 fielderror的提示信息可以国际化 2.非字段验证:actionErrors / <s:actionerror> 例 ...

  3. My数据库和Ms数据库的区别

    mssql 是微软的那个 SQL Server,运行于windows2000,2003等平台 mysql 是由瑞典mySQL AB 公司开发,目前属于Oracle旗下公司.可运行在windows平台. ...

  4. IM 融云 之 列表及封装

    // // ChatListIMViewController.m // testRongCloudIM // // Created by WoodGao on 16/1/8. // Copyright ...

  5. 安卓自定义类似TabHost的导航栏

    有时候为了项目需要我们要自定义一些导航控件,类似下面这样. 下面给大家讲讲我是怎么实现的, 1.素材准备(这个都是美工的事情) 2.①资源文件共有五个 如下: activity_main_first. ...

  6. php字符串比较

    比较两个字符串是否相等,最常见的方法就是使用“===”来判断,至于它和“==”的区别,简单来说 就是前者强调“identical”类型也要求一样:后者要求“equal”,值相同就可以了.或者使用str ...

  7. iOS 之 const

    const int a与 int const a一样. const int *a ;//指针可以修改,指向常整形的指针 int* const a;// 常指针, int* 作为一个整体被限制, 所以指 ...

  8. js原生设计模式——7原型模式之真正的原型模式——对象复制封装

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  9. HTML 颜色

    HTML 颜色 HTML 颜色由红色.绿色.蓝色混合而成. 颜色值 HTML 颜色由一个十六进制符号来定义,这个符号由红色.绿色和蓝色的值组成(RGB). 种颜色的最小值是0(十六进制:#00).最大 ...

  10. Bootstrap入门(三)<p>标签的css样式

    Bootstrap入门(三)<p>标签的css样式 前提:引入css文件,内容放在一个class为container的div中   <p>标签属性 1.“ text-left ...