栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

yadiChat-step2-全局聊天室

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

yadiChat-step2-全局聊天室

效果:

示例程序链接:https://yadiChat.orzlinux.cn

github地址:https://github.com/hqingLau/YadiChat

前文:

一、yadiChat-step1-登陆注册

目录

pom.xml

加入依赖,netty,序列化,会过期的map包(来管理session)。


    io.netty
    netty-all
    4.1.69.Final




    com.google.code.gson
    gson
    2.8.8




    net.jodah
    expiringmap
    0.5.10

session管理

之前我们将session由spring管理,现在我们改为自己管理。

UserSession.java

public class UserSession {
    private UserSession() {}
    public static void put(String sessionId,User user) {
        userMap.put(sessionId,user);
    }

    public static User get(String sessionId) {
        return userMap.getOrDefault(sessionId,null);
    }

    private static ExpiringMap userMap = ExpiringMap.builder().variableExpiration()
            .expiration(24*60, TimeUnit.MINUTES).expirationPolicy(ExpirationPolicy.CREATED).build();

    public static void update(String value) {
        userMap.put(value,userMap.get(value));
    }
}

这里面主要就是封装了一个会过期的map,这里设置为24小时过期,用来管理session。这样一段时间后,session过期,就会自动提示登录界面。

更改登录和注册逻辑,如:

UserController.java

@PostMapping("/login")
public String login(Model model, HttpServletRequest request, HttpServletResponse response) {
    String idname = request.getParameter("idname");
    String password = request.getParameter("password");
    User user = userService.login(new User(idname,null,password));
    if (user==null) {
        return "redirect:/signin";
    }
    String userUUID = idname;
    UserSession.put(userUUID,user);
    cookie cookie = new cookie("user",userUUID);
    cookie.setMaxAge(24*60*60); //一天过期
    // 配置cookie为主站cookie
    cookie.setDomain("orzlinux.cn");
    response.addcookie(cookie);
    return "redirect:/home";
}

session就是客户端放一个cookie作为sessionid,来服务器之后用这个sessionid查找对应的session。这里设置为主站cookie,这样在后期用到其它子域名的服务时cookie也能读取到,这里简单设置为用户idname。

接下来更改拦截策略:

UserInterceptor.java

public class UserInterceptor implements HandlerInterceptor  {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        if("/".equals(uri)||"/error".equals(uri)||"/signin".equals(uri)||"/login".equals(uri)||"/signup".equals(uri)||"/regist".equals(uri)) {
            return true;
        }
        cookie cookie = cookieUtils.getcookie(request.getcookies(),"user");
        if(cookie!=null) {
            UserSession.update(cookie.getValue());
            return true;
        }
        response.sendRedirect("/signin");
        return false;
    }
}

首先获取用户cookie,取UserSession查找,有就更新一下map,主要为了更新过期时间,没有就转到登录界面。

这里面需要获取cookie,为了方便使用封装成一个工具类:

cookieUtils.java

public class cookieUtils {
    public static cookie getcookie(javax.servlet.http.cookie[] cookies, String key) {
        if(cookies != null) {
            for (javax.servlet.http.cookie cookie : cookies) {
                if (cookie.getName().equals(key)) {
                    if (UserSession.get(cookie.getValue()) != null) {
                        return cookie;
                    }
                }
            }
        }
        return null;
    }
}

就是遍历,比较键值。

TextMsgBean

接下来要定义信息:

public class TextMsg {
    private String idname;
    private String nick_name;
    private String msg;
    private Date msgTime;
    // getter setter constructor
}

需要存储idname用户确定用户身份,昵称用于显示,消息具体内容,发送消息的时间。

全局消息数据库
# 建立全局聊天数据库
CREATE TABLE global_room_msg
(
    id INT NOT NULL AUTO_INCREMENT,
    id_name VARCHAR(128) NOT NULL ,
    nick_name VARCHAR(128) not null ,
    msg VARCHAR(10240) not null,
    msg_time DATETIME not null ,
    PRIMARY KEY (id),
    INDEX id_name(id_name)
);

同样,数据库配置。

TextMsgDao

这里用到了两个方法,向数据库插入一条消息,和获取过去的100条消息用于显示。

@Mapper
public interface TextMsgDao {
    int insert(TextMsg msg);
    List getLast100Msg();
}
TextMsgDao.xml

对应上面方法的数据库实现。





 
        insert into global_room_msg(id_name,nick_name,msg,msg_time) values(#{idname},#{nick_name},#{msg},#{msgTime})