文档章节

游戏服务器聊天模块的实现(二)

不爱睡的猪
 不爱睡的猪
发布于 2016/07/07 22:11
字数 691
阅读 69
收藏 0

    经过上一篇博客(游戏服务器聊天模块的实现)的介绍,聊天的模块基本流程可以跑通了,但是总感觉是一个空架子,没有什么实质性的作用。的确,如果是单纯的完成聊天消息的发送,没必要搞得这么复杂,既然是抽出模块,那当然是和聊天相关的功能都交给给模块来实现的了,比如什么聊天日志,禁言,监控,过滤等等。

    前段时间利用业余时间学习了一下netty,并利用netty写了简单的服务程序(https://github.com/lazysprite/simple_server),发现netty的事件传递很是有趣,所以这里就简单的模仿一下,用到聊天模块中,毕竟玩家发送的消息是需要层层处理才能够送达目的地的,做成责任链的形式减少代码中各种条件的判断,增加代码的美感,何乐而不为呢。居然选择链式处理,那么这个链到底放到哪里呢,ChatEntry?还是ChatService?我选择放在ChatSservice,这样好像在逻辑上面都比较容易说得通,当然放在ChatEntry身上也是有好处的,极端情况下每一个ChatEntry都何以有不同的处理,提出这样需求的策划大大们估计会被(省略少许字),举一个使用的例子,需求可能是这样的:提供一个策略,根据玩家发送敏感词汇的频率实行自动的短时间禁言。对于这样的需求如果让消息处理链与ChatEntry相关联,处理起来就会方便很多,当然也不是说消息处理链作为全局的就不能实现这样的功能,只是会稍微麻烦一点。

 public void communicate(long speaker, long listener, String message) {
        ChatEntry speakerEntry = getChatEntryById(speaker);
        if (speakerEntry == null) return;
        ChatEntry listenerEntry = getChatEntryById(listener);
        Dialogue dialogue = new SimpleDialogue(speaker, listener, message);
        try {
            readLock.lock();
            for (int i = 0; i < filters.size(); i++) {
                ChatFilter filter = filters.get(i);
                if (!filter.filter(dialogue)) {
                    dialogue.setCallBackCase(filter.getCase());
                    break;
                }
            }
        } finally {
            readLock.unlock();
        }
        if (dialogue.getCallBackCase() == CallBackCase.NORMAL) {
            speakerEntry.speak(listenerEntry, dialogue);
        } else {
            speakerEntry.speakCallback(dialogue);
        }
    }

经过简单改造后communicat方法就变成上面的样子,使用了可重入的读写锁来保证对filters这个可变状态的线程安全,这里的filters绝大部分时间都是提供一个遍历的功能,所以这里可以用CopyOnWriteArrayList来实现,无需加锁也能保证线程安全。

public interface ChatFilter {

    boolean filter(Dialogue dialogue);

    CallBackCase getCase();
}

filter这个接口目前只是简单的返回一个布尔值,然后在filter中要求设置失败的状态,以便回调给服务使用者,方便进行相应的处理。

© 著作权归作者所有

共有 人打赏支持
不爱睡的猪
粉丝 0
博文 4
码字总数 3197
作品 0
广州
程序员
私信 提问
Golang/python语言开发的分布式游戏服务器框架--mqant

mqant mqant 是一款基于 Golang 语言的简洁,高效,高性能的分布式游戏服务器框架,研发的初衷是要实现一款能支持高并发,高性能,高实时性的游戏服务器框架,也希望 mqant 未来能够做即时通...

梁大帅
2017/02/28
1K
1
BossHX/xingo_demo

xingo_demo xingo mmo大型多人在线游戏 带unity3d 客户端的服务器端demo xingo框架需要切换到no reflect 分支 git checkout noreflectveriosn 该demo实现了mmo游戏的基础模块aoi(基于兴趣范围...

BossHX
2016/12/21
0
0
用Python开发你的第一款聊天软件

在本实验中,我们将实现一个简单的图形界面聊天系统。我们可以通过图形客户端登录聊天室,并与其他成员进行聊天。 本教程由实验楼120发布在实验楼,完整教程、代码及在线练习地址:Python 实...

实验楼
2018/07/16
0
0
Android asmack使用介绍

XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的,最早是在Jabber上实现的。它继...

让代码飞一会
2015/07/10
0
0
android asmack 注册 登陆 聊天 多人聊天室 文件传输

XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的,最早是在Jabber上实现的。它继...

程序袁_绪龙
2014/11/28
0
1

没有更多内容

加载失败,请刷新页面

加载更多

Java单例模式学习记录

在项目开发中经常能遇见的设计模式就是单例模式了,而实现的方式最常见的有两种:饿汉和饱汉(懒汉)。由于日常接触较多而研究的不够深入,导致面试的时候被询问到后有点没底,这里记录一下学习...

JerryLin123
昨天
3
0
VSCODE 无法调试

VSCODE 无法调试 可以运行 可能的原因: GCC 的参数忘了加 -g

shzwork
昨天
4
0
理解去中心化 稳定币 DAI

随着摩根大通推出JPM Coin 稳定币,可以预见稳定币将成为区块链落地的一大助推器。 坦白来讲,对于一个程序员的我来讲(不懂一点专业经济和金融),理解DAI的机制,真的有一点复杂。耐心看完...

Tiny熊
昨天
4
0
5.线程实现

用于线程实现的Python模块 Python线程有时称为轻量级进程,因为线程比进程占用的内存少得多。 线程允许一次执行多个任务。 在Python中,以下两个模块在一个程序中实现线程 - _thread 模块 th...

Eappo_Geng
昨天
6
0
ServiceLoader

创建一个接口文件在resources资源目录下创建META-INF/services文件夹在services文件夹中创建文件,以接口全名命名创建接口实现类 内容me.zzp.ar.d.PostgreSQLDialectme.zzp.ar.d.Hype...

Cobbage
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部