美文网首页
[文档][电脑版][技术中心][电脑部]我聊(Mac)

[文档][电脑版][技术中心][电脑部]我聊(Mac)

作者: 绍清_shao | 来源:发表于2017-12-11 17:12 被阅读30次

我聊模块两个核心类

MJMessagesBubbleController类

MJMessagesBubbleController

MJStatusBarController类

MJStatusBarController

点击我聊图标,启动我聊过程详细步骤:

mj_modules::ShowMsgBubble("", true) {
  1. 判断是否登录和是否存在组织
  2. 是否启动应用ID为kDockClientMsgBoxIdentifierKey的应用
  (1).如果没启动则启动
  (2).如果有启动则获取MJStatusBarController全局单例,
  并调用showBubbleWithURL:base::SysUTF8ToNSString(str_url) openlast:is_open_last_new fromType:fromType]显示
}

- (void)showBubbleWithURL:(NSString*) str_url openlast:(bool)is_open_last_new fromType:(mj_modules::ShowMsgFromType)fromType {
  1. 判断是否从热键中启动
  2.[self showWindowWithTitle:str_title_ url:str_url profile:[self getProfile]] 显示
}

- (void)showWindowWithTitle:(NSString *)str_title url:(NSString *)str_url profile:(Profile *) profile{
  1. MJMessagesBubbleController 调用实例方法 showMessageBubble
}

- (void)showMessageBubble {
// 显示
}

Dock栏图标与115浏览器之间的通讯

当点击我聊图标时

  • MJStatusBarController类提供了一个类方法,全局获取单例 + (MJStatusBarController *)GetGloabInstance

  • 初始化方法中有对MJMessagesBubbleController的引用,以及监听应用菜单栏和dock栏我聊图标的状态.

  • Dock栏我聊显示属于第三方app,不是在115浏览器项目内.所以Dock栏上我聊图标的跟新显示已经启动我聊窗口,是通过进程之间的通讯实现。

  • 115浏览器内,启动Dock我聊以及状态栏图标时,添加了监听Dock栏我聊状态。

Dock栏我聊是个独立APP,作为消息的发送者,需要构建发送信息的数据:

// 生成Remote port
CFMessagePortRef remotePort;
remotePort = CFMessagePortCreateRemote(nil, (CFStringRef)kDistributedObjectServerForDockMsgBoxNameKey)

// 构建发送数据(string)
NSData *data = [NSJSONSerialization dataWithJSONObject:dicSend options:nil error:nil];
CFDataRef dataPtr = CFDataCreate(kCFAllocatorDefault,data.bytes, data.length);

// 执行发送操作
SInt32 status = CFMessagePortSendRequest(remotePort, messageID, dataPtr, timeout, timeout, NULL, NULL);
​

代码说明:

  • CFMessagePortCreateRemote会根据MACH_PORT_REMOTE定义的字符串为唯一标识获取消息接收者通过CFMessagePortCreateLocal使用相同字符串创建的底层mach port端口,从而实现向消息接收者发送信息。

115浏览器作为消息接收者,需要注册消息监听:

NSString *kDistributedObjectServerForDockMsgBoxNameKey = @"115Browser.MsgBox.Dock.Chanel";

if (localPort) {
                CFRelease(localPort);
            }
            if (runLoopSource) {
                CFRelease(runLoopSource);
            }
            localPort =  CFMessagePortCreateLocal(nil, (CFStringRef)kDistributedObjectServerForDockMsgBoxNameKey, CallbackMsgFromClient, nil,nil);
            runLoopSource = CFMessagePortCreateRunLoopSource(nil, localPort, 0);
            CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
             NSLog(@"start listenning");

代码说明:

  • 通过CFMessagePortCreateLocal可以创建一个本地CFMessagePortRef对象
  • CFMessagePort对象是靠一个字符串来唯一标识的,这一点非常重要,在这里字符串是由宏kDistributedObjectServerForDockMsgBoxNameKey定义的;
  • 创建CFMessagePort对象的同时设置了端口源事件的回调函数CallbackMsgFromClient,用于处理端口源事件;
  • 将创建的对象作为输入源添加到Runloop中,从而实现对端口源事件的监听,当Runloop收到对应的端口源事件时,会调用上一步中指定的回调芳芳;

在回调方法CallbackMsgFromClient内接受来自Dock栏我聊发送的信息。

static CFDataRef CallbackMsgFromClient(CFMessagePortRef port, SInt32 messageID, CFDataRef data, void *info)
{
NSLog(@"onRecvMessageCallBack is called");
.....
}

回调函数各个参数的含义为:

  • CFMessagePortRef local
    当前接收消息的CFMessagePortRef对象。
  • SInt32 msgid
    这个字段非常有用,用于标识消息。如果通信双方进程约定号每个msgid对应的数据结构,即可实现较为复杂的通信。
  • CFDataRef data
    通信的真正数据部分。
  • void *info
    为使用CFMessagePortCreateLocal方法创建port端口时指定的CFMessagePortContext对象的info字段,通常为空。
    该回调方法可以返回一个CFDataRef类型的数据给port消息的发送者,以实现有效的双方通信,这一点也非常重要。

相关文章

网友评论

      本文标题:[文档][电脑版][技术中心][电脑部]我聊(Mac)

      本文链接:https://www.haomeiwen.com/subject/ghuqgttx.html