IM系统第一章 -- 登录功能的实现

IM系统第一章 – 登录功能的实现

你是如何完成该功能的?

实现思路:我们可以想象一下微信qq的登录方式(我们预先在表中设置好了用户名单,就不需要注册了),来到一个登录窗口,输入完账号密码后就点击 ”登录“ 事件,然后将登录的请求协议 信息传入给服务端处理;服务端将请求协议的信息 与从数据库中获取到的信息进行查询校验后,将结果返回;若校验正确,还需要将该用户的 数据初始化(比如该用户和好友的通信记录,群组的通信记录等。。)并将这些结果返回给客户端,客户端根据请求应答 协议调用UI事件接口进行处理显示。

上面描述转化为下面的流程图 为:(参考 小傅哥

img

依旧是下面几个步骤:

  1. 自定义协议包;
  2. UI事件处理;
  3. 服务端对请求 协议进行处理;
  4. 客户端对请求应答 协议进行处理;

自定义协议:LoginRequest(登录请求协议)、LoginResponse (登录反馈协议)

public class LoginRequest extends Packet {
    private String userId;
    private String password;
    构造函数...
    set()/get()...
}

public class LoginResponse extends Packet {
    private String userId;  // 用户Id
    private String userHead;// 用户头像
    private String nickName;// 用户昵称
    private boolean success;// 校验结果
    private List<ChatTalkDto> chatTalkDtoList = new ArrayList<>(); // 聊天对话框数据[success is true]
    private List<GroupDto> groupsDtoList = new ArrayList<>(); // 群组列表
    private List<UserFriendDto> userFriendDtoList = new ArrayList<>(); // 好友列表
    构造函数...
    get()/set()...
}

再来看UI事件定义

public class LoginEvent implements ILoginEvent {
    // 事件登录校验
    @Override
    public void doLoginCheck(String userId,String userPassword) {
        Channel channel = BeanUtil.getBean("channel",Channel.class);
        // 将账号密码通过 登录请求协议一并通过channel送过去
        channel.writeAndFlush(new LoginRequest(userId,userPassword));
        // 记录当前的用户的用户id(是为了后面断线重连)
        CacheUtil.userId = userId;
    }
}

服务端:服务端负责的工作在前面 实现该功能的逻辑中 说的很清楚,这里不赘述;

将上面的逻辑转化为代码如下:

/*
注意:代码中涉及到的**Dto 其实都是跟PO相关的,只不过就是如果有些数据不需要加入或者多了某些字段就自行增加 **Dto这个类来替代。。
*/
public class LoginHandler extends MyBizHandler<LoginRequest> {
    @Override
    public void channelRead(Channel channel, LoginRequest msg) {
        // 1.登录失败
        boolean auth = userService.checkAuth(msg.getUserId(), msg.getUserPassword());
        if(!auth) {
            channel.writeAndFlush(new LoginResponse(false));
            return;
        }
        // 2.登录成功绑定Channel
        // 2.1 绑定用户id channel
        SocketChannelUtil.addChannel(msg.getUserId(),channel);
        // 2.2绑定群组 channel
        List<String> groupsIdList = userService.queryUserGroupsIdList(msg.getUserId());
        for (String groupId : groupsIdList) {
            SocketChannelUtil.addChannelGroup(groupId, channel);
        }
        // 3.反馈消息:用户消息、用户对话框消息、好友列表、群组列表
        // 组装消息包
        LoginResponse loginResponse = new LoginResponse();
        // 3.1 用户消息
        UserInfo userInfo = userService.queryService.queryUserInfo(msg.getUserId());
        // 3.2对话框消息
        List<TalkBoxInfo> talkBoxInfoList = userService.queryTalkBoxInfoList(msg.getUserId());
        for (TalkBoxInfo talkBoxInfo : talkBoxInfoList) {
           	/*
            下面就是对LoginResponse消息包中List<ChatTalkDto> chatTalkDtoList(聊天对话框列表)、List<GroupDto> 				groupsDtoList(群组列表)、List<UserFriendDto> userFriendDtoList(好友列表)进行包装,然后通过channel发			送  (因为代码太多,且容易理解就不发了)
           	*/
    }
        // 传输消息
        channel.writeAndFlush(loginResponse);
}

客户端接收到 来自服务端发送的 协议(LoginResponse)后,主要是进行调用UI接口进行信息的展示。(代码不展示了,暂时不是重点)

总结

最后我们回忆一下,实现该登录功能的逻辑:主要是服务端方面,需要对用户的channel进行绑定、对用户的群组channelGroup也需要进行绑定(至于为什么不绑定与好友的channel,我猜是因为只有建立双方通话的时候才需要绑定),就需要将请求应答 协议LoginResponse的内容进行填充(利用mybatis操作数据库);然后一并发给客户端处理就可以完成了。大概的流程就是如此;

最后还有就是服务端中配置的问题需要注意

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值