Kotlin + Netty 在 Android 上实现 Socket 的服务端(续篇)

一. 对原先 NettyServer 的改造

上一篇文章 《Kotlin + Netty 在 Android 上实现 Socket 的服务端》 ,曾经介绍的 NettyServer 其实只存了最后一次使用的 Channel。

Channel 是 Netty 网络操作抽象类,包括网络的读、写、发起连接、链路关闭等,它是 Netty 网络通信的主体。

在现实的开发中,服务端可能需要的是保存多个 Channel,例如存放到 ConcurrentHashMap。

当客户端连上服务端时,通过 NettyServer 的 addChannel() 将 channel 添加到 Map 中。当客户端断开服务端时,通过 NettyServer 的 removeChannel() 将 channel 从 Map 中移除。

为了安全考虑,服务端可能会主动断开某个 channel,则通过 NettyServer 的 disConnectChannel() 实现。

二. 通过 Service 方式启动 Netty 服务

2.1 NettyService 的实现

由于 App 中存在多个 Activity 会用到 Netty 的相关服务例如接受来自客户端的消息、发送消息到客户端,所以采用 Service 方式来启动 Netty 服务端是一种比较好的选择。

Service 跟 Activity 的交互也可以借助 EventBus 进行通信。

2.2 onStartCommand 的坑?

在使用 NettyService 时,发现会遇到如下的异常:

NettyService 是通过 startService() 启动,所以会调用 onStartCommand()。而使用 Kotlin 在创建 Service 时,默认的 onStartCommand() 方法是这样的:

但是 intent 存在为空的可能性,需要改成:

三. 对消息的封装

客户端和服务端之间传递的消息类型是 String 类型。即便是这样,还是要稍微定义一下 Message 的格式。

例如:

封装一个 NettyManager,它是单例,用于专门发送消息给客户端。

其中 sendMsg(msg: ()->String) 方法,它的参数是函数类型。将函数作为参数,可扩展性会更强。

Kotlin 的函数是第一等公民,函数就是对象,这是 Kotlin 作为函数式编程语言的重要特性。对象可以直接赋值给变量、可以作为某个函数的参数、也可以作为别的函数的返回值,那么函数也可以。

服务端发送消息给客户端:

四. 总结

本文是上一篇 《Kotlin + Netty 在 Android 上实现 Socket 的服务端》 的延续,介绍了如何做一个 Android 的 Netty 服务端、踩过的坑,以及如何封装消息。

关注【Java与Android技术栈】

更多精彩内容请 关注 扫码

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章