在网上看到一份比较 nice 的基于 webSocket 网页聊天项目,准备看看学习学习,如是有了这篇文章!原博主博客: http://blog.csdn.net/Amayadream/article/details/50551617
谢谢博主的文章和项目,我是抱着学习的态度,若有理解错的地方,请指正。
项目的功能说明去原博主博客看吧,项目上改进的地方,我具体做以下说明。
(1)webSocket 服务
对于 webSocket 服务代码,我进行一部分的封装和优化,主要是消息内容的封装、用户信息封装。
页面显示用户的昵称,指定用户昵称进行消息发送。
ChatServer.java
- package com.ccq.webSocket;
- import com.ccq.pojo.User;
- import com.ccq.utils.CommonDate;
- import net.sf.json.JSONObject;
- import org.apache.log4j.Logger;
- import javax.servlet.http.HttpSession;
- import javax.websocket. * ;
- import javax.websocket.server.PathParam;
- import javax.websocket.server.ServerEndpoint;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- /**
- * @author ccq
- * @Description webSocket服务
- * @date 2017/12/16 17:31
- */
- @ServerEndpoint(value = "/chatServer/{userid}", configurator = HttpSessionConfigurator.class) public class ChatServer {
- private static Logger logger = Logger.getLogger(ChatServer.class);
- private static int onlineCount = 0; // 记录连接数目
- // Map<用户id,用户信息>
- private static Map < String,
- OnlineUser > onlineUserMap = new ConcurrentHashMap < String,
- OnlineUser > (); //在线用户
- /**
- * 连接成功调用的方法
- */
- @OnOpen public void onOpen(@PathParam("userid") String userid, Session session, EndpointConfig config) {
- logger.info("[ChatServer] connection : userid = " + userid + " , sessionId = " + session.getId());
- // 增加用户数量
- addOnlineCount();
- // 获取当前用户的session
- HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
- User user = (User) httpSession.getAttribute("user"); // 获得当前用户信息
- // 将当前用户存到在线用户列表中
- OnlineUser onlineUser = new OnlineUser(user.getUserid(), user.getNickname(), session);
- onlineUserMap.put(user.getUserid(), onlineUser);
- // 通知所有在线用户,当前用户上线
- String content = "[" + CommonDate.getTime24() + " : " + user.getNickname() + "加入聊天室,当前在线人数为 " + getOnlineCount() + "位" + "]";
- JSONObject msg = new JSONObject();
- msg.put("content", content);
- String message = Message.getMessage(msg.toString(), Message.NOTICE, onlineUserMap.values());
- Message.broadcast(message, onlineUserMap.values());
- }
- /**
- * 连接关闭方法
- */
- @OnClose public void onClose(@PathParam("userid") String userid, Session session, CloseReason closeReason) {
- logger.info("[ChatServer] close : userid = " + userid + " , sessionId = " + session.getId() + " , closeCode = " + closeReason.getCloseCode().getCode() + " , closeReason = " + closeReason.getReasonPhrase());
- // 减少当前用户
- subOnlienCount();
- // 移除的用户信息
- OnlineUser removeUser = onlineUserMap.remove(userid);
- onlineUserMap.remove(userid);
- // 通知所有在线用户,当前用户下线
- String content = "[" + CommonDate.getTime24() + " : " + removeUser.getNickname() + " 离开聊天室,当前在线人数为 " + getOnlineCount() + "位" + "]";
- JSONObject msg = new JSONObject();
- msg.put("content", content);
- if (onlineUserMap.size() > 0) {
- String message = Message.getMessage(msg.toString(), Message.NOTICE, onlineUserMap.values());
- Message.broadcast(message, onlineUserMap.values());
- } else {
- logger.info("content : [" + CommonDate.getTime24() + " : " + removeUser.getNickname() + " 离开聊天室,当前在线人数为 " + getOnlineCount() + "位" + "]");
- }
- }
- /**
- * 接收客户端的message,判断是否有接收人而选择进行广播还是指定发送
- * @param data 客户端发来的消息
- */
- @OnMessage public void onMessage(@PathParam("userid") String userid, String data) {
- logger.info("[ChatServer] onMessage : userid = " + userid + " , data = " + data);
- JSONObject messageJson = JSONObject.fromObject(data);
- JSONObject message = messageJson.optJSONObject("message");
- String to = message.optString("to");
- String from = message.optString("from");
- // 将用户id转换为名称
- to = this.userIdCastNickName(to);
- OnlineUser fromUser = onlineUserMap.get(from);
- String sendMessage = Message.getContent(fromUser, to, message.optString("content"), message.optString("time"));
- String returnData = Message.getMessage(sendMessage, messageJson.optString("type"), null);
- if (to == null || to.equals("")) { // 进行广播
- Message.broadcast(returnData.toString(), onlineUserMap.values());
- } else {
- Message.singleSend(returnData.toString(), onlineUserMap.get(from)); // 发送给自己
- String[] useridList = message.optString("to").split(",");
- for (String id: useridList) {
- if (!id.equals(from)) {
- Message.singleSend(returnData.toString(), onlineUserMap.get(id)); // 分别发送给指定的用户
- }
- }
- }
- }
- /**
- * 发生错误
- * @param throwable
- */
- @OnError public void onError(@PathParam("userid") String userid, Session session, Throwable throwable) {
- logger.info("[ChatServer] close : userid = " + userid + " , sessionId = " + session.getId() + " , throwable = " + throwable.getMessage());
- }
- public static int getOnlineCount() {
- return onlineCount;
- }
- public synchronized void addOnlineCount() {
- onlineCount++;
- }
- public synchronized void subOnlienCount() {
- onlineCount--;
- }
- /**
- * 将用户id转换为名称
- * @param userIds
- * @return
- */
- private String userIdCastNickName(String userIds) {
- String niceNames = "";
- if (userIds != null && !userIds.equals("")) {
- String[] useridList = userIds.split(",");
- String toName = "";
- for (String id: useridList) {
- toName = toName + onlineUserMap.get(id).getNickname() + ",";
- }
- niceNames = toName.substring(0, toName.length() - 1);
- }
- return niceNames;
- }
- }
OnlineUser.java
- public class OnlineUser {
- private String userid;
- private String nickname;
- private Session session;
- }
Message.java
- package com.ccq.webSocket;
- import net.sf.json.JSONArray;
- import net.sf.json.JSONObject;
- import org.apache.commons.collections.CollectionUtils;
- import org.apache.log4j.Logger;
- import javax.websocket.Session;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- /**
- * @author ccq
- * @Description 消息类
- * @date 2017/12/16 19:08
- */
- public class Message {
- private static Logger logger = Logger.getLogger(Message.class);
- /**
- * 消息类型
- */
- public static String NOTICE = "notice"; //通知
- public static String MESSAGE = "message"; //消息
- /**
- * 组装信息返回给前台
- * @param message 交互信息
- * @param type 信息类型
- * @param userList 在线列表
- * @return
- *
- * "massage" : {
- * "from" : "xxx",
- * "to" : "xxx",
- * "content" : "xxx",
- * "time" : "xxxx.xx.xx"
- * },
- * "type" : {notice|message},
- * "list" : {[xx],[xx],[xx]}
- */
- public static String getMessage(String message, String type, Collection < OnlineUser > userList) {
- JSONObject msg = new JSONObject();
- msg.put("message", message);
- msg.put("type", type);
- if (CollectionUtils.isNotEmpty(userList)) {
- List < String > propertys = new ArrayList < String > ();
- propertys.add("session");
- JSONArray userListArray = JSONArray.fromObject(userList, JsonConfigUtils.getJsonConfig(propertys));
- msg.put("list", userListArray);
- }
- return msg.toString();
- }
- /**
- * 消息内容
- * @param fromUser
- * @param to
- * @param content
- * @param time
- * @return
- * {
- * "from" : "xxx",
- * "to" : "xxx",
- * "content" : "xxx",
- * "time" : "xxxx.xx.xx"
- * }
- */
- public static String getContent(OnlineUser fromUser, String to, String content, String time) {
- JSONObject contentJson = new JSONObject();
- // 转化为json串时去掉session,用户session不能被序列化
- List < String > propertys = new ArrayList < String > ();
- propertys.add("session");
- contentJson.put("from", JSONObject.fromObject(fromUser, JsonConfigUtils.getJsonConfig(propertys)));
- contentJson.put("to", to);
- contentJson.put("content", content);
- contentJson.put("time", time);
- return contentJson.toString();
- }
- /**
- * 广播消息
- * @param message 消息
- * @param onlineUsers 在线用户
- */
- public static void broadcast(String message, Collection < OnlineUser > onlineUsers) {
- /***************************在线用户***************************/
- StringBuffer userStr = new StringBuffer();
- for (OnlineUser user: onlineUsers) {
- userStr.append(user.getNickname() + ",");
- }
- userStr.deleteCharAt(userStr.length() - 1);
- logger.info("[broadcast] message = " + message + ", onlineUsers = " + userStr.toString());
- /***************************在线用户***************************/
- for (OnlineUser user: onlineUsers) {
- try {
- user.getSession().getBasicRemote().sendText(message);
- } catch(IOException e) {
- e.printStackTrace();
- logger.info("消息发送失败!" + e.getMessage());
- continue;
- }
- }
- }
- /**
- * 对特定用户发送消息
- * @param message
- * @param onlineUser
- */
- public static void singleSend(String message, OnlineUser onlineUser) {
- logger.info("[singleSend] message = " + message + ", toUser = " + onlineUser.getNickname());
- try {
- onlineUser.getSession().getBasicRemote().sendText(message);
- } catch(IOException e) {
- e.printStackTrace();
- logger.info("消息发送失败!" + e.getMessage());
- }
- }
- }
(2) 用户头像上传
在网上找了一个 amazeui 的图片上传,可以对图片进行裁剪,地址: http://www.jq22.com/jquery-info13022
确实比较好用,贴一下主要代码
- @RequestMapping(value = "{userid}/upload", method = RequestMethod.POST, produces = "application/json; charset=utf-8")@ResponseBody public String updateUserPassword(@PathVariable("userid") String userid, String image, HttpServletRequest request) {
- JSONObject responseJson = new JSONObject();
- String filePath = "I:\\IDEA2017-02\\img\\";
- String PicName = UUID.randomUUID().toString() + ".png";
- String header = "data:image";
- String[] imageArr = image.split(",");
- if (imageArr[0].contains(header)) { //是img的
- // 去掉头部
- image = imageArr[1];
- // 修改图片
- BASE64Decoder decoder = new BASE64Decoder();
- try {
- byte[] decodedBytes = decoder.decodeBuffer(image); // 将字符串格式的image转为二进制流(biye[])的decodedBytes
- String imgFilePath = filePath + PicName; //指定图片要存放的位
- File targetFile = new File(filePath);
- if (!targetFile.exists()) {
- targetFile.mkdirs();
- }
- FileOutputStream out = new FileOutputStream(imgFilePath); //新建一个文件输出器,并为它指定输出位置imgFilePath
- out.write(decodedBytes); //利用文件输出器将二进制格式decodedBytes输出
- out.close();
- // 修改图片
- User user = userService.getUserById(userid);
- user.setProfilehead(PicName);
- int flag = userService.updateUser(user);
- if (flag > 0) {
- Log log = LogUtil.setLog(userid, CommonDate.getTime24(), WordDefined.LOG_TYPE_UPDATE, WordDefined.LOG_DETAIL_UPDATE_PROFILEHEAD, NetUtil.getIpAddress(request));
- logService.insertLog(log);
- } else {
- responseJson.put("result", "error");
- responseJson.put("msg", "上传失败!");
- }
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
- responseJson.put("result", "ok");
- responseJson.put("msg", "上传成功!");
- responseJson.put("fileUrl", "/pic/" + PicName);
- return responseJson.toString();
- }
3、改进的图片
来源: http://blog.csdn.net/qq_27717967/article/details/78826475