现在的位置: 首页 > 综合 > 正文

陌生人聊天系统

2013年09月22日 ⁄ 综合 ⁄ 共 2948字 ⁄ 字号 评论关闭

前几天突然看到北邮人论坛出现了陌生人聊天系统(尽管基本一直没什么人^^),于是跟随者论坛的回帖看到了在北邮人论坛上线这个系统的人发的帖子,大体的设计思路是在服务器端运行一个Memcached守护程序,并为客户端使用php或js编写一个界面程序,之后即可以balabala了.....


先是关于Memcached的简介:


Memcached是什么?
  Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。但是它并不提供冗余(例如,复制其hashmap条目);当某个服务器S停止运行或崩溃了,所有存放在S上的键/值对都将丢失。
  Memcached由Danga Interactive开发,用于提升LiveJournal.com访问速度的。LJ每秒动态页面访问量几千次,用户700万。Memcached将数据库负载大幅度降低,更好的分配资源,更快速访问。


如何使用memcached-Server端?
  在服务端运行:
  # ./memcached -d -m 2048 -l 10.0.0.40 -p 11211
  这将会启动一个占用2G内存的进程,并打开11211端口用于接收请求。由于32位系统只能处理4G内存的寻址,所以在大于4G内存使用PAE的32位服务器上可以运行2-3个进程,并在不同端口进行监听。


如何使用memcached-Client端?
  在应用端包含一个用于描述Client的Class后,就可以直接使用,非常简单。
  PHP Example:
  $options["servers"] = array("192.168.1.41:11211", "192.168.1.42:11212");
  $options["debug"] = false;
  $memc = new MemCachedClient($options);
  $myarr = array("one","two", 3);
  $memc->set("key_one", $myarr);
  $val = $memc->get("key_one");
  print $val[0]."/n"; // prints 'one‘
  print $val[1]."/n"; // prints 'two‘
  print $val[2]."/n"; // prints 3
  采用memcached网站演示:
  http://blog.lyxcf.com/5864.lyxcf




接下来是北邮哥们的经验介绍:

详见:http://xw2423.byr.edu.cn/blog/archives/709


终于这个系统可以告一段落了,进过了这几天的赶工,搁置各种工作,毅然上线了这个系统,链接http://bbs.byr.cn/chat 。之所以要做这个类似于omegle的东西,也只是想熟悉一下memcached的使用,下面稍微为阐述一下系统思路:

首先是交互方式的确定,以现在的web技术水平,这种web在线聊天系统还是会选用定期的轮询作为技术的出发点,基于html5的websocket长连接在近期是有些文章但我看过的demo还是没有,另外论坛的访问很大一部分都是ie浏览器,所以不可能用这么新的技术。

其次是数据的存储,当然我最初就是为了用memcached而做这个系统,当然memcached也挺适合这种短时间内高并发的读写。其实在写的过程中还考虑过用传统的关系数据库和NoSql的数据库。其实用数据库也是可行的,但是要多做一些操作,比如过期的检测,由于基于web的聊天系统对于被动断线是不可能捕捉到的,这就意味这系统需要及时踢除没有心跳的用户。使用缓存系统能很好的解决这个问题,而对于数据库则需要自行维护数据的过期。这里提到两种不同的数据库还是有本质的区别,memcached与nosql对于数据的存储本质上是一样的或者也可以把memcached也归为nosql的一种。这种数据库相比于关系数据库来说在条件查询上捉襟见肘,这就需要我们不仅维护数据还要维护数据的索引,这也是我在写的过程中渐渐发现的(原来没有做过 nosql的开发)。其实用mysql的内存表来做这个应用,我想也是一种很好的选择。

技术方案确定后就是数据结构,由于是kv系统,必须自行维护数据的索引供搜索使用,每个聊天的用户都有相应一个uid作为UUID,每个用户的数据在memcached中有一条记录,也就是相应的用户对象的序列化值。一个用户的数据包括

uid:唯一确定身份的id

id:用户id

cuid:陌生人uid

lat:last access time

status:用户状态

action:用户行为

queue:消息数组

然后整个系统无非就是一个状态机,根据不同的请求跳转到不同的状态。这里说一下消息的传递,用户发送消息先存储存在自己的queue中,陌生人轮询,如果queue中存在消息就取回来并清空queue数组,这样用户消息也不会长时间的积累,系统也不保存任何用户聊天记录。

其余的就没什么好说的了,就是一些js的交互,自己js也写的够寒碜的,有点惨不忍睹的地步了。这个系统暂且就这样吧,也没有太多时间进行维护了,希望以后有人能把他做的更好。下面记录一下memcached的相关安装

memcached直接在官方网站下载源码包即可,也就是其服务器端。地址是:http://memcached.org/ 解压缩后


1 #./configure --prefix=/usr/local/memcached
2 #make
3 #sudo make install

值得注意的是memcached需要libevent的支持,没有的话再configure会报错,这个直接可以再源上找到,安装libevent-devel就可以了。
memcached的使用方法很简单直接运行bin下memcached即可,-h选项有详细的参数说明,我的运行参数是:

memcached -d -m 128 -u root -p XXXX -c 256  -v

一般来说都是用root用户来运行,而且memcached如果监听了整个网络的话没有ACL的机制,这就意味着如果别人知道机器 memcached的端口就可以直接通信了,这俨然是缺乏安全的行为。网上对此也有很多解决方法,比如说用内网的方式,memcached服务器在内网里面,这样外网的用户就不可能访问到了。当然在unix下最直接的方法就是用iptables,指定ip访问指定端口。

对于memcached的客户端,不同语言有不同的实现。在php中有两种客户端供选择memcache和memcached,后者看过去比前者功能稍多。我用的是前者,从http://pecl.php.net/package/memcache 下载安装包,解压缩后


1 #phpize
2 #./configure --enable-memcache
3 #make

把编译出来的so文件在php.ini中加载即可


抱歉!评论已关闭.