默认
发表评论 7
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
[已回复] 对接MobileIMSDK的登录逻辑问题,如果同时手机号和账号登录?
阅读(51845) | 评论(7 收藏 淘帖1
//登录
case ProtocalType.C.FROM_CLIENT_TYPE_OF_LOGIN:
{
   PLoginInfo loginInfo = ProtocalFactory.parsePLoginInfo(pFromClient.getDataContent());
   //             logger.info("[IMCORE]>> 客户端" + remoteAddress + "发过来的登陆信息内容是:getLoginName=" +
   //                   loginInfo.getLoginName() + "|getLoginPsw=" + loginInfo.getLoginPsw());

   if (this.serverEventListener != null)
   {
      int _try_user_id = OnlineProcessor.getUserIdFromSession(session);

      boolean alreadyLogined = _try_user_id != -1;

      if (alreadyLogined)
      {
         //                   logger.debug("[IMCORE]>> 【注意】客户端" + remoteAddress + "的会话正常且已经登陆过,而此时又重新登陆:getLoginName=" +
         //                         loginInfo.getLoginName() + "|getLoginPsw=" + loginInfo.getLoginPsw());

         boolean sendOK = sendData(session, ProtocalFactory.createPLoginInfoResponse(
               ProtocalType.CONST.LOGIN$ALREADY_LOGINED, String.valueOf(_try_user_id)));
         if (sendOK)
         {
            // 将用户登陆成功后的id暂存到会话对象中备用
            session.setAttribute(OnlineProcessor.USER_ID_IN_SESSION_ATTRIBUTE, _try_user_id);
            // 将用户登陆成功后的登陆名暂存到会话对象中备用
            //session.setAttribute(OnlineProcessor.LOGIN_NAME_IN_SESSION_ATTRIBUTE, loginInfo.getLoginUserId());
            // 将用户信息放入到在线列表中(理论上:每一个存放在在线列表中的session都对应了user_id)
            OnlineProcessor.getInstance().putUser(loginInfo.getLoginUserId(), session);
            this.serverEventListener.onUserLoginAction_CallBack(loginInfo, session);
            break;
         }

         logger.warn("[IMCORE]>> 发给客户端" + remoteAddress + "的登陆成功信息发送失败了!");
         break;
      }
      //验证用户密码
      int code = this.serverEventListener.onVerifyUserCallBack(loginInfo,session);
      if (code==ProtocalType.CONST.LOGIN$SUCCESS)
      {
         int user_id = loginInfo.getId();

         boolean sendOK = sendData(session, ProtocalFactory.createPLoginInfoResponse(code, String.valueOf(user_id)));
         if (sendOK)
         {
            // 将用户登陆成功后的id暂存到会话对象中备用
            session.setAttribute(OnlineProcessor.USER_ID_IN_SESSION_ATTRIBUTE, user_id);
            // 将用户登陆成功后的登陆名暂存到会话对象中备用
            //session.setAttribute(OnlineProcessor.LOGIN_NAME_IN_SESSION_ATTRIBUTE, loginInfo.getLoginUserId());
            // 将用户信息放入到在线列表中(理论上:每一个存放在在线列表中的session都对应了user_id)
            //OnlineProcessor.getInstance().putUser(user_id, session, loginInfo.getLoginUserId());
            OnlineProcessor.getInstance().putUser(loginInfo.getLoginUserId(), session);

            this.serverEventListener.onUserLoginAction_CallBack(loginInfo, session);

            break;
         }
         logger.warn("[IMCORE]>> 发给客户端" + remoteAddress + "的登陆成功信息发送失败了!");
         break;
      }
      //登录失败
      sendData(session, ProtocalFactory.createPLoginInfoResponse(code, -1+""));
      break;
   }

   //logger.warn("[IMCORE]>> 收到客户端" + remoteAddress + "登陆信息,但回调对象是null,没有进行回调.");
   break;
}

这是源码,目前遇到的问题是这样的:
  • 1)客户端主动登录,用手机号码登录的,但是如果掉线就从本地自动登录 本地自动登录用的是账号,而不是手机号码,这样会导致在线用户出现问题
  • 2)手机号码登录和账号登录的session不一样
  • 3)如果要做到手机号码登录和账号登录一样,该怎么处理


即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

标签:MobileIMSDK
上一篇:[已回复] MobileIMSDK v3.0版当客户端登录成功后,如何获取到当前登录账号?下一篇:[已回复] MobileIMSDK v3.0客户端sendCommonData服务器收不到数据?

本帖已收录至以下技术专辑

推荐方案
评论 7
你的思路有问题,最佳实践应该是这样的:

  • 1)在你的客户端拿着用户名或手机号或邮箱 或者其它任何你系统定义的账号方式,加上密码等提交你的http接口进行登陆身份认证:
    大型系统里这个接口可能是SSO单点登陆接口;
  • 2)第1步的http接口认证成功后应该返回用户id和token:
    用户id:无论他是用什么方式登陆,存在你数据库里的用户id主键肯定是唯一的吧,token:这个token你可以自已定义,用于连接im时使用;
  • 3)接着你的客户端再用返回的用户id和token来连接IM服务器就行了:
    IM服务器只要拿着你的用户id和刚才的SSO单点登陆接给的token就可以通过SSO服务端提供的token验证机制来完成身份认证了。

说白了,用户的身份认证和连接IM要各自分开(一共2步),这样才是最佳实践,因为通常情况下im和http服务可能有是独立分开部署的,这样容易处理好性能以及运维问题。
引用:JackJiang 发表于 2017-11-22 14:38
你的思路有问题,最佳实践应该是这样的:

还有就是互踢的问题 我是做了这个操作,但是有问题,就是发送3指令让退出,代码是这样的
签名: Java服务端通过OnlineProcessor up = OnlineProcessor.getInstance();拿到的对象和IM ...
引用:JackJiang 发表于 2017-11-22 14:38
你的思路有问题,最佳实践应该是这样的:

public void putUser(String user_id, IoSession session)
        {
                if(onlineSessions.containsKey(user_id))
                {
                        logger.debug("[IMCORE]【注意】用户id="+user_id+"已经在在线列表中了,session也是同一个吗?"
                                        +(onlineSessions.get(user_id).hashCode() == session.hashCode()));
                       
                        // TODO 同一账号的重复登陆情况可在此展开处理逻辑
                        if(onlineSessions.get(user_id).hashCode() != session.hashCode()) {
                                try {
                                        sendData(onlineSessions.get(user_id), ProtocalFactory.createPLoginInfoResponse(3, user_id));
                                } catch (Exception e) {
                                        e.printStackTrace();
                                }
                        }

                        __printOnline();

                }
               
                onlineSessions.put(user_id, session);
               
                __printOnline();// just for debug
        }
签名: Java服务端通过OnlineProcessor up = OnlineProcessor.getInstance();拿到的对象和IM ...
引用:db123 发表于 2017-11-22 14:48
public void putUser(String user_id, IoSession session)
        {
                if(onlineSessions.containsKey(user_i ...

参考这贴:
[已回复] MobileIMSDK服务端的多设备登陆互踢问题求助
引用:JackJiang 发表于 2017-11-22 14:56
参考这贴:
《[已回复] MobileIMSDK服务端的多设备登陆互踢问题求助》

我看了,他那个发送的不是3指令 我发3指令应该也没有问题吧
签名: Java服务端通过OnlineProcessor up = OnlineProcessor.getInstance();拿到的对象和IM ...
引用:db123 发表于 2017-11-22 14:58
我看了,他那个发送的不是3指令 我发3指令应该也没有问题吧

按照你自已的逻辑实现即可,没有通用套路

评分

1

查看评分

今天才发现这么好的网站,都是干货啊!箴言
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部