Permalink
Browse files

add chatofpomelo

  • Loading branch information...
1 parent ce9b73d commit 8e2cc5a4a7d80b2c314698eb14cf8dd114284ba9 py committed Nov 20, 2012
View
@@ -1,4 +1,51 @@
-chatofpomelo
-============
+## Chatofpomelo
-chat application of pomelo
+A simple chat room experiment using pomelo framework and html5.
+The chat server currently runs on nodejs v0.8, and should run fine on the latest stable as well.It requires the following npm libraries:
+- pomelo
+- express
+- crc
+
+Both of them can be installed via 'sh npm-install.sh' (it will install a local copy of all the dependencies in the node_modules directory)
+
+## Viewing
+
+ * Visit [demo game github](http://github.com/py8765/chatofpomelo)to get the source code and install it on your local machine.
+
+## Configuration
+
+ * The server setting (server number, host and port, etc.) can be configured in 'game-server/config/servers.json' and 'game-server/config/master.json' files.
+ * Other settings (log4js, redis, aoi, etc.) also can be configured in 'config' folder.
+
+## Deployment
+Enter chatofpomelo/game-server, and run 'pomelo start' or 'node app.js' in order to start the game server.
+Enter chatofpomelo/web-server, and run 'node app.js' in order to start the web server, and access '3001' port (which can be changed in 'app_express.js') to load game.
+
+## Monitoring
+
+Pomelo framework provides monitoring tool: AdminConsole. After game is loaded, you can access '7001' port and monitor the game information(operating-system, process, userInfo, sceneInfo, etc.).
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2012 Netease, Inc. and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
@@ -0,0 +1,25 @@
+var pomelo = require('pomelo');
+var routeUtil = require('./app/util/routeUtil');
+/**
+ * Init app for client.
+ */
+var app = pomelo.createApp();
+app.set('name', 'chatofpomelo');
+app.defaultConfiguration();
+
+
+// app configure
+app.configure('production|development', function() {
+ // route configures
+ app.route('chat', routeUtil.chat);
+
+ // filter configures
+ app.filter(pomelo.timeout());
+});
+
+// start app
+app.start();
+
+process.on('uncaughtException', function(err) {
+ console.error(' Caught exception: ' + err.stack);
+});
@@ -0,0 +1,63 @@
+var chatRemote = require('../remote/chatRemote');
+
+module.exports = function(app) {
+ return new Handler(app);
+};
+
+var Handler = function(app) {
+ this.app = app;
+};
+
+var handler = Handler.prototype;
+
+/**
+ * Send messages to users
+ *
+ * @param {Object} msg message from client
+ * @param {Object} session
+ * @param {Function} next next stemp callback
+ *
+ */
+handler.send = function(msg, session, next) {
+ var channelService = this.app.get('channelService');
+ var param = {
+ route: 'onChat',
+ msg: msg.content,
+ from: msg.from,
+ target: msg.target
+ };
+ channel = channelService.getChannel(msg.rid, false);
+
+ //the target is all users
+ if(msg.target == 0) {
+ channel.pushMessage(param);
+ }
+ //the target is specific user
+ else {
+ var tuid = msg.target + '*' + msg.rid;
+ var tsid = channel.getMember(tuid)['sid'];
+ channelService.pushMessageByUids(param, [{
+ uid: tuid,
+ sid: tsid
+ }]);
+ }
+ next(null, {
+ route: msg.route
+ });
+};
+
+/**
+ * Get online users
+ *
+ * @param {Object} msg message from client
+ * @param {Object} session
+ * @param {Function} next next stemp callback
+ *
+ */
+handler.getUsers = function(msg, session, next) {
+ var remote = chatRemote(this.app);
+ var users = remote.get(msg.rid, false);
+ next(null, {
+ users: users
+ });
+};
@@ -0,0 +1,63 @@
+module.exports = function(app) {
+ return new ChatRemote(app);
+};
+
+var ChatRemote = function(app) {
+ this.app = app;
+ this.channelService = app.get('channelService');
+};
+
+/**
+ * Add user into chat channel.
+ *
+ * @param {String} uid unique id for user
+ * @param {String} sid server id
+ * @param {String} name channel name
+ * @param {boolean} flag channel parameter
+ * @param {Callback} cb
+ *
+ */
+ChatRemote.prototype.add = function(uid, sid, name, flag, cb) {
+ var channel = this.channelService.getChannel(name, flag);
+ if( !! channel) {
+ channel.add(uid, sid);
+ }
+ cb(this.get(name, flag));
+};
+
+/**
+ * Get user from chat channel.
+ *
+ * @param {Object} opts parameters for request
+ * @param {String} name channel name
+ * @param {boolean} flag channel parameter
+ * @return {Array} users uids in channel
+ *
+ */
+ChatRemote.prototype.get = function(name, flag) {
+ var users = [];
+ var channel = this.channelService.getChannel(name, flag);
+ if( !! channel) {
+ users = channel.getMembers();
+ }
+ for(var i = 0; i < users.length; i++) {
+ users[i] = users[i].split('*')[0];
+ }
+ return users;
+};
+
+/**
+ * Kick user out chat channel.
+ *
+ * @param {String} uid unique id for user
+ * @param {String} sid server id
+ * @param {String} name channel name
+ *
+ */
+ChatRemote.prototype.kick = function(uid, sid, name) {
+ var channel = this.channelService.getChannel(name, false);
+ // leave channel
+ if( !! channel) {
+ channel.leave(uid, sid);
+ }
+};
@@ -0,0 +1,64 @@
+module.exports = function(app) {
+ return new Handler(app);
+};
+
+var Handler = function(app) {
+ this.app = app;
+ };
+
+var handler = Handler.prototype;
+
+/**
+ * New client entry chat server.
+ *
+ * @param {Object} msg request message
+ * @param {Object} session current session object
+ * @param {Function} next next stemp callback
+ * @return {Void}
+ */
+handler.enter = function(msg, session, next) {
+ var self = this;
+ var rid = msg.rid;
+ var uid = msg.username + '*' + rid
+ var sessionService = self.app.get('sessionService');
+
+ //duplicate log in
+ if( !! sessionService.getByUid(uid)) {
+ next(null, {
+ code: 500,
+ error: true
+ });
+ return;
+ }
+
+ session.bind(uid);
+ session.set('rid', rid);
+ session.push('rid', function(err) {
+ if(err) {
+ console.error('set rid for session service failed! error is : %j', err.stack);
+ }
+ });
+ session.on('closed', onUserLeave.bind(null, self.app));
+
+ //put user into channel
+ self.app.rpc.chat.chatRemote.add(session, uid, self.app.get('serverId'), rid, true, function(users) {
+ next(null, {
+ code: 200,
+ users: users
+ });
+ });
+};
+
+/**
+ * User log out handler
+ *
+ * @param {Object} app current application
+ * @param {Object} session current session object
+ *
+ */
+var onUserLeave = function(app, session) {
+ if(!session || !session.uid) {
+ return;
+ }
+ app.rpc.chat.chatRemote.kick(session, session.uid, app.get('serverId'), session.get('rid'), null);
+ };
@@ -0,0 +1,44 @@
+var dispatcher = require('../../../util/dispatcher');
+
+module.exports = function(app) {
+ return new Handler(app);
+};
+
+var Handler = function(app) {
+ this.app = app;
+};
+
+var handler = Handler.prototype;
+
+/**
+ * Gate handler that dispatch user to connectors.
+ *
+ * @param {Object} msg message from client
+ * @param {Object} session
+ * @param {Function} next next stemp callback
+ *
+ */
+handler.queryEntry = function(msg, session, next) {
+ var uid = msg.uid;
+ if(!uid) {
+ next(null, {
+ code: 500
+ });
+ return;
+ }
+ // get all connectors
+ var connectors = this.app.getServersByType('connector');
+ if(!connectors || connectors.length === 0) {
+ next(null, {
+ code: 500
+ });
+ return;
+ }
+ // select connector
+ var res = dispatcher.dispatch(uid, connectors);
+ next(null, {
+ code: 200,
+ host: res.host,
+ port: res.wsPort
+ });
+};
@@ -0,0 +1,6 @@
+var crc = require('crc');
+
+module.exports.dispatch = function(uid, connectors) {
+ var index = Math.abs(crc.crc32(uid)) % connectors.length;
+ return connectors[index];
+};
@@ -0,0 +1,15 @@
+var exp = module.exports;
+var dispatcher = require('./dispatcher');
+
+exp.chat = function(session, msg, app, cb) {
+ var chatServers = app.getServersByType('chat');
+
+ if(!chatServers || chatServers.length === 0) {
+ cb(new Error('can not find chat servers.'));
+ return;
+ }
+
+ var res = dispatcher.dispatch(session.get('rid'), chatServers);
+
+ cb(null, res.id);
+};
Oops, something went wrong.

0 comments on commit 8e2cc5a

Please sign in to comment.