Java后台使用Websocket教程
在开发一个项目的时候使用到了WebSocket协议
- 什么是WebSocket?
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
2.使用
- 工具类
package com.mz.usps.common.component; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; //该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。
@ServerEndpoint("/webSocket/{id}")
@Component("webSocket")
public class WebSocket { private static Logger logger = Logger.getLogger(WebSocket.class);
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//concurrent包的线程安全Map,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static ConcurrentMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();
private static ConcurrentMap<String, WebSocket> webSocketMapAdmin = new ConcurrentHashMap<>(); public Session getSession() {
return session;
} public static WebSocket getWebSocket(String id) {
return webSocketMap.get(id);
} /**
* 连接建立成功调用的方法
*
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(Session session, @PathParam("id") String id) {
this.session = session;
//String sessionId = session.getId();
webSocketMap.put(id, this); //加入map中
if (id.contains("admin")) {// 后台登陆用户,加入list
webSocketMapAdmin.put(id, this);
}
addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
} /**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam("id") String id) {
webSocketMap.remove(id); //从map中删除
webSocketMapAdmin.remove(id);
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
} /**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public static void onMessage(String message, Session session) {
//群发消息
if (webSocketMapAdmin.size() > 0) {
for (WebSocket item : webSocketMapAdmin.values()) {
try {
//System.out.println(item.session.getId());
item.session.getBasicRemote().sendText(message);
} catch (IOException e) {
logger.error("IO异常");
continue;
}
}
} } /**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
//System.out.println("发生错误");
logger.error("发生错误");
} /**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
} public static synchronized int getOnlineCount() {
return onlineCount;
} public static synchronized void addOnlineCount() {
WebSocket.onlineCount++;
} public static synchronized void subOnlineCount() {
WebSocket.onlineCount--;
} public static void main(String[] args) {
/*WebSocket webSocket = new WebSocket();
System.out.println(webSocket);
webSocketMap.put("1", webSocket);
webSocketMap.put("1", webSocket);
System.out.println(webSocketMap.get("12"));*/
onMessage("123465",null);
}
} - 微信登录成功时将用户信息发送给前端
/**
* 手机端微信登陆
*
* @return
*/
@RequestMapping(value = "/wxLogin", method = RequestMethod.GET)
@ResponseBody
public R wxLogin(String userResult, String state, @RequestParam(required = false, value = "userId") String userId) throws Exception {
//System.out.println(userResult+"\n"+state+"\n"+userId);
WxUser wxUser = JSON.parseObject(userResult, WxUser.class);
UserInfo userInfo = new UserInfo();
userInfo.setUnionId(wxUser.getUnionid());
userInfo.setOpenid(wxUser.getOpenid());
userInfo.setSex((long) wxUser.getSex());
userInfo.setHeadImgUrl(wxUser.getHeadimgurl());
if (EmojiUtil.containsEmoji(wxUser.getNickName())) {
logger.info(wxUser.getNickName());
userInfo.setNickName(EmojiUtil.emojiConverterToAlias(wxUser.getNickName()));
} else {
userInfo.setNickName(wxUser.getNickName());
}
System.out.println(userInfo.getUnionId());
UserInfo userInfo1;
WebSocket webSocket = WebSocket.getWebSocket(state);
Map<String, Object> m = new HashMap<>();
//登录
if (userId == null || "".equals(userId)) {
if ((userInfo1 = userInfoService.selectWx(userInfo)) != null) {
//判定账号是否被禁用
if (userInfo1.getUserState() != 1) {
R r = new R();
r.put("code", 500);
r.put("msg", "此账号因为特殊原因已被禁用,若想重新启用,请联系管理员");
webSocket.sendMessage(JSON.toJSONString(r));
return null;
} userInfo.setUserId(userInfo1.getUserId());
//System.out.println(userInfo1.getHeadImgUrl()+"你好呀");
if (userInfo1.getHeadImgUrl() != null) {
userInfo.setHeadImgUrl(null);
}
//System.out.println(userInfo.getHeadImgUrl()+"你好");
userInfoService.updateByPrimaryKeySelective(userInfo);
UserInfo userInfo2 = userInfoService.selectWx(userInfo);
if (EmojiUtil.containsEmoji(userInfo2.getNickName())) {
userInfo2.setNickName(EmojiUtil.emojiConverterUnicodeStr(userInfo2.getNickName()));
}
m.put("openId", userInfo2.getOpenid());
m.put("userId", userInfo2.getUserId());
m.put("createTime", new Date());
String javaWebToken = WebTokenUtil.createJavaWebToken(m);
userInfo2.setToken(javaWebToken);
redisCache.setValue(javaWebToken, "1", 1, TimeUnit.DAYS);
webSocket.sendMessage(JSON.toJSONString(userInfo2));//登录用户信息发送给web
return R.ok("登录成功");
} else {
userInfo.setUserName(userInfo.getNickName());
userInfoService.insertSelective(userInfo);
UserInfo userInfo3 = userInfoService.selectWx(userInfo);
if (EmojiUtil.containsEmoji(userInfo3.getNickName())) {
userInfo3.setNickName(EmojiUtil.emojiConverterUnicodeStr(userInfo3.getNickName()));
}
//判定账号是否被禁用
if (userInfo3.getUserState() != 1) {
R r = new R();
r.put("code", 500);
r.put("msg", "此账号因为特殊原因已被禁用,若想启用,请联系管理员");
webSocket.sendMessage(JSON.toJSONString(r));
return null;
} System.out.println(userInfo.getOpenid());
m.put("openId", userInfo3.getOpenid());
m.put("userId", userInfo3.getUserId());
m.put("createTime", new Date());
String javaWebToken = WebTokenUtil.createJavaWebToken(m);
userInfo3.setToken(javaWebToken);
redisCache.setValue(javaWebToken, "1", 1, TimeUnit.DAYS);
webSocket.sendMessage(JSON.toJSONString(userInfo3));//登录用户信息发送给web
return R.ok("登录成功");
}
} else {
userInfo.setUserId(Long.valueOf(userId));
//绑定微信前先判断数据库中是否有头像,如果有,不更改头像
List<UserInfo> selectmemberlist = userInfoService.selectmemberlist(userInfo);
if (selectmemberlist.get(0).getHeadImgUrl() != null) {
userInfo.setHeadImgUrl(null);
} UserInfo userInfo2 = userInfoService.selectWx(userInfo);
if (userInfo2 != null) {
R r = new R();
r.put("code", 500);
r.put("msg", "此微信已被注册,若确认是你本人微信,请联系管理员帮你更改");
webSocket.sendMessage(JSON.toJSONString(r));
return R.error("");
}
if (EmojiUtil.containsEmoji(wxUser.getNickName())) {
userInfo.setNickName( EmojiUtil.emojiConverterToAlias(wxUser.getNickName()));
}
R r = userInfoService.updateByPrimaryKeySelective(userInfo);
if (r.get("code").equals(200)) {
R r1 = new R();
r1.put("code", 200);
r1.put("msg", "更改成功");
webSocket.sendMessage(JSON.toJSONString(r1));
} else {
R r2 = new R();
r2.put("code", 500);
r2.put("msg", "更改失败");
webSocket.sendMessage(JSON.toJSONString(r2));
}
return r;
}
} }
- 工具类
Java后台使用Websocket教程的更多相关文章
- WebSocket实现Java后台消息推送
1.什么是WebSocket WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端. 2.实现原理 在实现 ...
- fastJson java后台转换json格式数据
什么事JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...
- Java 后台创建word 文档
---恢复内容开始--- Java 后台创建 word 文档 自己总结 网上查阅的文档 分享POI 教程地址:http://www.tuicool.com/articles/emqaEf6 方式一. ...
- 坚持:学习Java后台的第一阶段,我学习了那些知识
最近的计划是业余时间学习Java后台方面的知识,发现学习的过程中,要学的东西真多啊,让我一下子感觉很遥远.但是还好我制定了计划,自己选择的路,跪着也要走完!关于计划是<终于,我还是下决心学Jav ...
- 微信小程序与java后台交互
java后台使用的ssm框架,小程序连接的本地接口.跟正常的web访问没什么区别,也是后台获取url,返回json数据:只是小程序前台请求的url要带上http://localhost:80801. ...
- 【分享】Java后台开发精选知识图谱
地址 引言: 学习一个新的技术时,其实不在于跟着某个教程敲出了几行.几百行代码,这样你最多只能知其然而不知其所以然,进步缓慢且深度有限,最重要的是一开始就对整个学习路线有宏观.简洁的认识,确定大的学习 ...
- 非科班双非本科投的337家Java后台(励志)
考试结束,班级平均分只拿到了年级第二,班主任于是问道:大家都知道世界第一高峰珠穆朗玛峰,有人知道世界第二高峰是什么吗?正当班主任要继续发话,只听到角落默默想起来一个声音:”乔戈里峰” 前言 文章出自h ...
- WebSocket 教程(转载)
WebSocket 教程 作者: 阮一峰 日期: 2017年5月15日 WebSocket 是一种网络通信协议,很多高级功能都需要它. 本文介绍 WebSocket 协议的使用方法. 一.为什么需 ...
- form表单提交中文乱码(前台中文到JAVA后台乱码)问题及解决
form表单提交中文乱码(前台中文到JAVA后台乱码)问题及解决 一.问题: 页面输入框中的中文内容,在后台乱码,导致搜索功能失效:(详细可以见后面的重现) 二.原因: 浏览器对于数据的默认编码格式为 ...
随机推荐
- python&django 实现页面中关联查询小功能(中级篇)
目的 组合搜索实现如下图功能 知识点 1.使用自定义标签模板(templatetags) 实现 models.py 和 views.py和初级篇一样 重点如下:在app01目录下创建templatet ...
- anylogic 使用
1.智能体群的用法有人会问:请问怎么给生成的两个对象赋予属性,比如在分叉的时候一个进入sink1,另一个进入sink2?我想source生成不同的实体,而且各个实体都有不同的属性,请问应该怎么设置呢? ...
- find 命令局部小结之 xtime
大家在使用find命令的时候往往会使用它的 -name 或者 -xtime,在这里就说下他的xtime. find / -mtime +7 .find / -mtime -7.find / -mti ...
- java接口,接口的特性,接口实现多态,面向接口编程
package cn.zy.cellphone; /**接口是一种引用数据类型.使用interface声明接口,形式 * 形式:public interface 接口名称{} * 接口不能拥有构造方法 ...
- P3436 [POI2006]PRO-Professor Szu
P3436 [POI2006]PRO-Professor Szu 题目描述 n个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条 ...
- Python爬去有道翻译
注:传入的类型为POST类型,所以需要使用urllib.parse.urlencode(),将字典转换成URL可用参数: 使用json.loads(),将输出的json格式,转换为字典类型 impor ...
- Linux安装docker
1.检查内核版本,必须是3.10及以上 uname ‐r 2.安装docker yum install docker 3.输入y确认安装 4.启动docker [root@localhost ~]# ...
- 数据库根据id排序
select * from 表名 order by id 根据 id 从小到大排序
- kubernetes集群网络配置方案
1. 直接路由 在每个节点上添加其他节点的静态路由,就可以将不同物理机的docker0网桥互联互通. 我的两个节点的IP分别为:172.16.252.218和172.16.252.209. 两个doc ...
- 2018-2019-2 网络对抗技术 20165328 Exp6 信息收集与漏洞扫描
目录 实验要求 基础问题回答: 实验过程: 各种搜索技巧的应用及DNS IP注册信息的查询 基本扫描技术 漏洞扫描--使用OpenVAS 实验感想 实验要求 (1)各种搜索技巧的应用 (2)DNS I ...