作者:vousiu
出处:http://www.cnblogs.com/vousiu
本实例参考自Mike Cantelon等人的《Node.js in Action》一书。
本实例要实现如下一个聊天App。左上的“Winter”为显示的房间的名字。中间为聊天消息,斜体字为系统消息,非斜体为聊天内容。右侧为房间列表,点击房间名可以进入房间。在下方输入框输入内容后,点击“提交”则可以发送聊天信息,或者发送更改昵称和更换房间的指令。
整个程序的架构图如下:
文件目录结构如下所示:
其中,socket.io包提供了一些webSocket方法,它可以跟http服务器在同一个端口进行监听,socket服务器可以对用户的连接和事件以回掉函数的方式进行响应。
chat_server.js用socket.io写了一个聊天服务器,处理与聊天相关的事件。它有一系列变量来存储每个socket所对应的名字、房间号还有系统已占用的名字。在每个用户与其建立connection时,它用回调函数为这个用户赋一个名字和房间,然后为这个用户的每个socket设置一个回调。有的回调就对发出的用户进行响应,有的则需要对一批用户进行响应(比如有人进了他们的房间),就像下图所示:
chat_server监听 <--------- connect ---------- 用户上线
chat_server处理 <--------- socket.io --------- 用户界面命令(chat.js中的函数)
处理完毕 ----------- socket.io--------> 界面更新(chat_ui.js中的回调函数来处理)
----- (broadcast) socket.io --------> 一批用户的界面
chat_server监听 <-------- disconnect -------- 用户下线
这个chat_server同时对多个用户的connection进行相应,那会不会造成在多线程中经常出现的问题:给多个用户分配同一个名字呢?按我的理解是不会的,因为它是一个connection一个connection的处理,对一个用户的connection回调函数执行完前,另一个用户的包含在connection回调函数中的名字分配函数不会进入node队列。
chat.js中定义了向一个socket发送各种消息和指令的函数。
chat_ui.js定义了在界面加载完时执行的一个回调,该回调注册了:对于用户界面操作的相应函数 和 对于socket.io的响应函数。
index.html和style.css则提供了用户界面。
最后,server.js在3000端口进行监听和文件传输,默认传输index.html文件。它还有一个对于文件的缓存功能。然后启动了chat_server服务器。
除了对于功能的实现,对于这个实例的一个关注点就是,它是一个Node程序,因此很多地方是使用异步回调函数的方法来写的,会出现一个回调套一个回调,里面再套一个回调的写法,这值得写惯了传统程序的程序员进行注意。
对于这些文件中代码的具体内容,将在接下来的文章中做具体介绍。