Websocket即时通信应用开发 java部分
2016-02-01 12:46
351 查看
前面的文章中,我们知道了前台的js部分了,那么现在我们就来讲讲Java服务器上面的部分。
在编写代码前,需要一个jar包:websocket.jar,值得注意的是,这个包是在tomcat的jar包中,在我们编码的时候可以将它复制过来就可以了,然后将编好的代码在不报错的情况下进行编译,但是我们在使用它部署的时候需要删掉这个jar包,不然他会和这个tomcat的jar有冲突的。为此在这里有这几项需要注意:
a.需要websocket.jar包,这个包在tomcat中,直接复制过来就可以了。
b.进行Java编码,代码不出错,编译下,这里只是让他生成class文件,无法使用,这是jar包会冲突。
c.删除原本复制过来的websocket.jar包,这时所有的代码会报错,但是没关系,因为在上一步中我们已经生成好了class文件,这样原本报错的代码是不会执行的,真正执行的是上一步中的class文件中的内容。最后运行访问就会成功了。
注:每次修改好的代码需要在有jar包的情况下进行编译。需要访问的时候删除jar包。
代码的实现:以注解的方式。
@ServerEndpoint("/webSocket/{userName}")
public class WebSocket {
// 线程机制
//private static final AtomicInteger connect = new AtomicInteger(0);
// Map记录用户
private static final Map<String, Object> userConnect = new HashMap<String, Object>();
// serviceList记录在线客服人员
private static final List<Kefu> serviceList = new ArrayList<Kefu>();
// 用户昵称
private String userName;
private Session session;
private Log logger = LogFactory.getLog(this.getClass());
/**
* 类的初始化操作,通过线程,生成用户的昵称编号。
*/
public WebSocket() {
String user = TOURIST + connect.getAndIncrement();
}
/**
* 用户与服务器建立连接,并响应客户端。
*
* @param session
* @throws IOException
*/
@OnOpen
public void open(@PathParam("userName") String userName, Session session)
throws IOException {
this.session = session;
this.userName = userName;
JSONObject json = new JSONObject();
// 记录所有与服务器在线连接的用户
userName = new String(userName.getBytes("ISO-8859-1"), "utf-8");// 解决中文乱码
userConnect.put(userName, this);
// 推送消息
String msg = String.format("%s %s", userName, "已在线!");
// 客服人员登录,则向所有在线用户推送客服在线的消息。
if (userName.substring(0, 4).equals("bwkf")) {// 判断是客服人员,将客服人员的信息保存到serviceList中
json.put("msg", msg);
json.put("operation", "kf_connect");
int flag = 0;
for (Kefu k : serviceList) {
if (k.getName().equals(userName)) {
flag = 1;
}
}
if (flag != 1) {
Kefu kefu = new Kefu();
kefu.setName(userName);
serviceList.add(kefu);
}
System.out.println("json...." + json.toString());
session.getBasicRemote().sendText(json.toString());// 连接成功时,响应客户端。
for (String key : userConnect.keySet()) {
if (!key.substring(0, 4).equals("bwkf")) {//向用户推送客服在线的消息
WebSocket user = (WebSocket) userConnect.get(key);
JSONObject js = new JSONObject();
js.put("operation", "kf_connect_send");
js.put("kf", userName);
// System.out.println("js...."+js.toString());
user.session.getBasicRemote().sendText(js.toString());// 推送在线消息
}
}
4000
} else {// 客户人员登录,将所有的客服人员的信息推送给客户
JSONArray jn = new JSONArray();
for (int i = 0; i < serviceList.size(); i++) {
JSONObject j = new JSONObject();
j.put("kf", serviceList.get(i).getName());
j.put("operation", "kh_connect");
jn.add(j);
}
System.out.println("jn....." + jn.toString());
session.getBasicRemote().sendText(jn.toString());// 连接成功时,响应客户端。
}
}
@OnClose
public void close() throws IOException {
userConnect.remove(this.userName);// 移除连接
if (this.userName.substring(0, 4).equals("bwkf")) {// 如果是客服人员下线
for (String key : userConnect.keySet()) {
System.out.println("username..." + key);
if (!key.substring(0, 4).equals("bwkf")) {// 给非客服人员推送消息
WebSocket user = (WebSocket) userConnect.get(key);
JSONObject js = new JSONObject();
userName = new String(userName.getBytes("ISO-8859-1"),
"utf-8");// 解决中文乱码
js.put("operation", "kf_connect_clsoe");
js.put("kf", userName);
System.out.println("js...." + js.toString());
try{
user.session.getBasicRemote().sendText(js.toString());// 推送在线消息
} catch(Exception e){
System.out.println("出错了......");
e.printStackTrace();
}
}
}
for (int i=0;i<serviceList.size();i++) {
if (this.userName.equals(serviceList.get(i).getName())) {
serviceList.remove(i);
}
}
}
}
// 发送消息
@OnMessage
public void send(String message) {
JSONObject json = JSONObject.fromObject(message);
// 解析出需要发送的用户名称
String userNameTo = json.get("to").toString();
String content = json.get("content").toString();
System.out.println("userNameTo......" + userNameTo + " content...."
+ content);
// 将消息封装
String filteredMessage = String
.format("%s: %s", this.userName, content);
sendMsg(filteredMessage, userNameTo);
}
// 用户消息的推送方法
public void sendMsg(String message, String userNameTo) {
sendUser(message, userNameTo);
}
// 发送消息给指定的用户
public void sendUser(String message, String userNameTo) {
// 获取指定用户
WebSocket c = (WebSocket) userConnect.get(userNameTo);
MDC.put("FROMNAME", this.userName);// 通过日志文件将消息存入数据库
MDC.put("TONAME", userNameTo);
MDC.put("MSGINFO", message);
MDC.put("CHATID", System.currentTimeMillis());
logger.info("");
logger.debug("");
try {
// 向指定的用户发送消息
// System.out.println(message);
// 将消息内容封装成json数据
JSONObject json = new JSONObject();
json.put("from", this.userName);
json.put("content", message);
json.put("operation", "message");
c.session.getBasicRemote().sendText(json.toString());
} catch (Exception e) {
userConnect.remove(c);
e.printStackTrace();
try {
c.session.close();
} catch (Exception e1) {
e1.printStackTrace();
}
String msg = String.format("* %s %s", c.userName,
"has been disconnected.");
sendMsg(msg, userNameTo);
}
}
代码分析:
在编写代码前,需要一个jar包:websocket.jar,值得注意的是,这个包是在tomcat的jar包中,在我们编码的时候可以将它复制过来就可以了,然后将编好的代码在不报错的情况下进行编译,但是我们在使用它部署的时候需要删掉这个jar包,不然他会和这个tomcat的jar有冲突的。为此在这里有这几项需要注意:
a.需要websocket.jar包,这个包在tomcat中,直接复制过来就可以了。
b.进行Java编码,代码不出错,编译下,这里只是让他生成class文件,无法使用,这是jar包会冲突。
c.删除原本复制过来的websocket.jar包,这时所有的代码会报错,但是没关系,因为在上一步中我们已经生成好了class文件,这样原本报错的代码是不会执行的,真正执行的是上一步中的class文件中的内容。最后运行访问就会成功了。
注:每次修改好的代码需要在有jar包的情况下进行编译。需要访问的时候删除jar包。
代码的实现:以注解的方式。
@ServerEndpoint("/webSocket/{userName}")
public class WebSocket {
// 线程机制
//private static final AtomicInteger connect = new AtomicInteger(0);
// Map记录用户
private static final Map<String, Object> userConnect = new HashMap<String, Object>();
// serviceList记录在线客服人员
private static final List<Kefu> serviceList = new ArrayList<Kefu>();
// 用户昵称
private String userName;
private Session session;
private Log logger = LogFactory.getLog(this.getClass());
/**
* 类的初始化操作,通过线程,生成用户的昵称编号。
*/
public WebSocket() {
String user = TOURIST + connect.getAndIncrement();
}
/**
* 用户与服务器建立连接,并响应客户端。
*
* @param session
* @throws IOException
*/
@OnOpen
public void open(@PathParam("userName") String userName, Session session)
throws IOException {
this.session = session;
this.userName = userName;
JSONObject json = new JSONObject();
// 记录所有与服务器在线连接的用户
userName = new String(userName.getBytes("ISO-8859-1"), "utf-8");// 解决中文乱码
userConnect.put(userName, this);
// 推送消息
String msg = String.format("%s %s", userName, "已在线!");
// 客服人员登录,则向所有在线用户推送客服在线的消息。
if (userName.substring(0, 4).equals("bwkf")) {// 判断是客服人员,将客服人员的信息保存到serviceList中
json.put("msg", msg);
json.put("operation", "kf_connect");
int flag = 0;
for (Kefu k : serviceList) {
if (k.getName().equals(userName)) {
flag = 1;
}
}
if (flag != 1) {
Kefu kefu = new Kefu();
kefu.setName(userName);
serviceList.add(kefu);
}
System.out.println("json...." + json.toString());
session.getBasicRemote().sendText(json.toString());// 连接成功时,响应客户端。
for (String key : userConnect.keySet()) {
if (!key.substring(0, 4).equals("bwkf")) {//向用户推送客服在线的消息
WebSocket user = (WebSocket) userConnect.get(key);
JSONObject js = new JSONObject();
js.put("operation", "kf_connect_send");
js.put("kf", userName);
// System.out.println("js...."+js.toString());
user.session.getBasicRemote().sendText(js.toString());// 推送在线消息
}
}
4000
} else {// 客户人员登录,将所有的客服人员的信息推送给客户
JSONArray jn = new JSONArray();
for (int i = 0; i < serviceList.size(); i++) {
JSONObject j = new JSONObject();
j.put("kf", serviceList.get(i).getName());
j.put("operation", "kh_connect");
jn.add(j);
}
System.out.println("jn....." + jn.toString());
session.getBasicRemote().sendText(jn.toString());// 连接成功时,响应客户端。
}
}
@OnClose
public void close() throws IOException {
userConnect.remove(this.userName);// 移除连接
if (this.userName.substring(0, 4).equals("bwkf")) {// 如果是客服人员下线
for (String key : userConnect.keySet()) {
System.out.println("username..." + key);
if (!key.substring(0, 4).equals("bwkf")) {// 给非客服人员推送消息
WebSocket user = (WebSocket) userConnect.get(key);
JSONObject js = new JSONObject();
userName = new String(userName.getBytes("ISO-8859-1"),
"utf-8");// 解决中文乱码
js.put("operation", "kf_connect_clsoe");
js.put("kf", userName);
System.out.println("js...." + js.toString());
try{
user.session.getBasicRemote().sendText(js.toString());// 推送在线消息
} catch(Exception e){
System.out.println("出错了......");
e.printStackTrace();
}
}
}
for (int i=0;i<serviceList.size();i++) {
if (this.userName.equals(serviceList.get(i).getName())) {
serviceList.remove(i);
}
}
}
}
// 发送消息
@OnMessage
public void send(String message) {
JSONObject json = JSONObject.fromObject(message);
// 解析出需要发送的用户名称
String userNameTo = json.get("to").toString();
String content = json.get("content").toString();
System.out.println("userNameTo......" + userNameTo + " content...."
+ content);
// 将消息封装
String filteredMessage = String
.format("%s: %s", this.userName, content);
sendMsg(filteredMessage, userNameTo);
}
// 用户消息的推送方法
public void sendMsg(String message, String userNameTo) {
sendUser(message, userNameTo);
}
// 发送消息给指定的用户
public void sendUser(String message, String userNameTo) {
// 获取指定用户
WebSocket c = (WebSocket) userConnect.get(userNameTo);
MDC.put("FROMNAME", this.userName);// 通过日志文件将消息存入数据库
MDC.put("TONAME", userNameTo);
MDC.put("MSGINFO", message);
MDC.put("CHATID", System.currentTimeMillis());
logger.info("");
logger.debug("");
try {
// 向指定的用户发送消息
// System.out.println(message);
// 将消息内容封装成json数据
JSONObject json = new JSONObject();
json.put("from", this.userName);
json.put("content", message);
json.put("operation", "message");
c.session.getBasicRemote().sendText(json.toString());
} catch (Exception e) {
userConnect.remove(c);
e.printStackTrace();
try {
c.session.close();
} catch (Exception e1) {
e1.printStackTrace();
}
String msg = String.format("* %s %s", c.userName,
"has been disconnected.");
sendMsg(msg, userNameTo);
}
}
代码分析:
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 2015-2016网页设计趋势分析 Web Design of Trends
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序