em-websocket-server 0.1.2 → 0.13

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,63 +1,56 @@
1
- #em-websocket-server
2
-
3
- * em-websocket-server allows the creation of efficient, evented, websocket services
4
-
5
- ##Installation
6
-
7
- If you don't have gemcutter
8
-
9
- gem install gemcutter
10
- gem tumble
11
-
12
- Otherwise
13
-
14
- gem install em-websocket-server
15
-
16
- Or
17
-
18
- gem install em-websocket-server -s http://gemcutter.org
19
-
20
- ##Dependencies
21
- - eventmachine http://github.com/eventmachine/eventmachine
22
-
23
- ##Docs
24
-
25
- Not yet... coming soon
26
-
27
- ##Quick Example
28
-
29
- require 'rubygems'
30
- require 'em-websocket-server'
31
- require 'json'
32
-
33
- #create a channel for pub sub
34
- $chatroom = EM::Channel.new
35
-
36
- class ChatServer < WebSocket::Server
37
-
38
- #subscribe to the channel on client connect
39
- def on_connect
40
- @sid = $chatroom.subscribe do |msg|
41
- send_message msg
42
- end
43
- end
44
-
45
- #unsubscribe on client disconnect
46
- def on_disconnect
47
- $chatroom.unsubscribe(@sid)
48
- end
49
-
50
- #publish the message to the channel on
51
- #client message received
52
- def on_receive msg
53
- $chatroom.push msg
54
- end
55
-
56
- end
57
-
58
- #start the event machine on port 8000 and have
59
- #it instantiate ChatServer objects for each
60
- #client connection
61
- EM.run do
62
- EM.start_server "0.0.0.0", 8000, ChatServer
63
- end
1
+ #em-websocket-server
2
+
3
+ * em-websocket-server allows the creation of efficient, evented, websocket services
4
+
5
+ ##Installation
6
+
7
+ gem install em-websocket-server -s http://gemcutter.org
8
+
9
+ ##Dependencies
10
+ - eventmachine http://github.com/eventmachine/eventmachine
11
+
12
+ ##Docs
13
+
14
+ Not yet... coming soon
15
+
16
+ ##Quick Example
17
+
18
+ require 'rubygems'
19
+ require 'em-websocket-server'
20
+ require 'json'
21
+
22
+ #create a channel for pub sub
23
+ $chatroom = EM::Channel.new
24
+
25
+ class ChatServer < WebSocket::Server
26
+
27
+ #subscribe to the channel on client connect
28
+ def on_connect
29
+ @sid = $chatroom.subscribe do |msg|
30
+ send_message msg
31
+ end
32
+ end
33
+
34
+ #unsubscribe on client disconnect
35
+ def on_disconnect
36
+ $chatroom.unsubscribe(@sid)
37
+ end
38
+
39
+ #publish the message to the channel on
40
+ #client message received
41
+ def on_receive msg
42
+ $chatroom.push msg
43
+ end
44
+
45
+ end
46
+
47
+ #start the event machine on port 8000 and have
48
+ #it instantiate ChatServer objects for each
49
+ #client connection
50
+ EM.run do
51
+ EM.start_server "0.0.0.0", 8000, ChatServer
52
+ end
53
+
54
+ ##Thanks
55
+ sidonath
56
+ TheBreeze
@@ -1,25 +1,32 @@
1
- spec = Gem::Specification.new do |s|
2
- s.name = 'em-websocket-server'
3
- s.version = '0.1.2'
4
- s.date = '2009-12-14'
5
- s.summary = 'An evented ruby websocket server built on top of EventMachine'
6
- s.email = "dan.simpson@gmail.com"
7
- s.homepage = "http://github.com/dansimpson/em-websocket-server"
8
- s.description = "An evented ruby websocket server built on top of EventMachine"
9
- s.has_rdoc = false
10
-
11
-
12
- s.authors = ["Dan Simpson"]
13
- s.add_dependency('eventmachine', '>= 0.12.4')
14
-
15
-
16
- s.files = [
17
- "README.markdown",
18
- "em-websocket-server.gemspec",
19
- "lib/web_socket.rb",
20
- "lib/web_socket/util.rb",
21
- "lib/web_socket/frame.rb",
22
- "lib/web_socket/client.rb",
23
- "lib/web_socket/server.rb"
24
- ]
25
- end
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'em-websocket-server'
3
+ s.version = '0.13'
4
+ s.date = '2009-12-14'
5
+ s.summary = 'An evented ruby websocket server built on top of EventMachine'
6
+ s.email = "dan.simpson@gmail.com"
7
+ s.homepage = "http://github.com/dansimpson/em-websocket-server"
8
+ s.description = "An evented ruby websocket server built on top of EventMachine"
9
+ s.has_rdoc = false
10
+
11
+
12
+ s.authors = ["Dan Simpson"]
13
+ s.add_dependency('eventmachine', '>= 0.12.4')
14
+
15
+
16
+ s.files = [
17
+ "README.markdown",
18
+ "em-websocket-server.gemspec",
19
+ "examples/chat.rb",
20
+ "examples/chat.html",
21
+ "examples/timesync.html",
22
+ "examples/timesync.rb",
23
+ "examples/tictactoe/tictactoe.html",
24
+ "examples/tictactoe/tictactoe.js",
25
+ "examples/tictactoe/tictactoe.rb",
26
+ "lib/web_socket.rb",
27
+ "lib/web_socket/client.rb",
28
+ "lib/web_socket/server.rb",
29
+ "lib/web_socket/frame.rb",
30
+ "lib/web_socket/util.rb"
31
+ ]
32
+ end
@@ -0,0 +1,37 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>em-websocket-server test</title>
5
+ </head>
6
+ <body>
7
+
8
+
9
+ <h1>em-websocket-server chat demo</h1>
10
+ <div id="chat">connecting....</div>
11
+
12
+ <script>
13
+
14
+ var webSocket = new WebSocket('ws://localhost:8000/time');
15
+
16
+ webSocket.onopen = function(event){
17
+ document.getElementById('chat').innerHTML = 'connected';
18
+ };
19
+
20
+ webSocket.onmessage = function(event){
21
+ document.getElementById('chat').innerHTML += "<br/>" + event.data;
22
+ };
23
+
24
+ webSocket.onclose = function(event){
25
+ document.getElementById('chat').innerHTML = 'socket closed';
26
+ };
27
+
28
+ document.getElementById('chatty').addEventListener("onkeypress", function() {
29
+ webSocket.send("test");
30
+ });
31
+
32
+ </script>
33
+
34
+ <a href="#" onclick="webSocket.send('test')">Send Test</a>
35
+
36
+ </body>
37
+ </html>
data/examples/chat.rb ADDED
@@ -0,0 +1,70 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'rubygems'
4
+ require 'web_socket'
5
+ require 'json'
6
+
7
+ $chatroom = EM::Channel.new
8
+ $messages = 0
9
+
10
+ class ChatServer < WebSocket::Server
11
+
12
+ def on_connect
13
+ puts "Server -> Connect"
14
+ @sid = $chatroom.subscribe do |msg|
15
+ send_message msg
16
+ end
17
+ end
18
+
19
+ def on_disconnect
20
+ puts "Server -> Handle Disconnect"
21
+ $chatroom.unsubscribe(@sid)
22
+ end
23
+
24
+ def on_receive msg
25
+
26
+ $messages += 1
27
+ if($messages % 100 == 0)
28
+ puts $messages
29
+ end
30
+
31
+ $chatroom.push(msg)
32
+ end
33
+
34
+ end
35
+
36
+ class ChatClient < WebSocket::Client
37
+
38
+ def initialize *args
39
+ super
40
+ end
41
+
42
+ def on_disconnect
43
+ puts "Client -> Disconnected"
44
+ end
45
+
46
+ def on_connect
47
+
48
+ EM.add_periodic_timer(rand() * 8, EM.Callback(self, :on_timer))
49
+
50
+ puts "Client -> connected"
51
+
52
+ end
53
+
54
+ def on_timer
55
+ send_message "x"
56
+ end
57
+
58
+ def on_receive msg
59
+ end
60
+
61
+ end
62
+
63
+ EM.kqueue
64
+
65
+ EM.run do
66
+ EM.start_server "0.0.0.0", 8000, ChatServer
67
+ 5.times do
68
+ EM.connect "localhost", 8000, ChatClient
69
+ end
70
+ end
@@ -0,0 +1,51 @@
1
+ <!doctype html>
2
+
3
+ <html>
4
+ <head>
5
+ <title>Tic Tac Toe</title>
6
+ <meta name="author" content="Jordan Fowler (TheBreeze)">
7
+
8
+ <style type="text/css" media="screen">
9
+ #navigation ul {
10
+ list-style-type: none;
11
+ padding: 0;
12
+ margin: 25px 0px;
13
+ }
14
+
15
+ #navigation ul li {
16
+ display: inline;
17
+ padding: 0;
18
+ margin: 0;
19
+ margin-right: 10px;
20
+ }
21
+
22
+ #game-board .cell {
23
+ width: 100px;
24
+ height: 100px;
25
+ padding: 5px;
26
+ background: #000;
27
+ color: #FFF;
28
+ font-size: 100px;
29
+ text-align: center;
30
+ vertical-align: middle;
31
+ }
32
+ </style>
33
+ </head>
34
+ <body>
35
+
36
+ <h1>Tic Tac Toe</h1>
37
+
38
+ <div id="user-count"></div>
39
+ <div id="game-stats"></div>
40
+ <div id="status"></div>
41
+
42
+ <table id="game-board">
43
+ <tr><td id="cell-0-0" class="cell"></td><td id="cell-1-0" class="cell"></td><td id="cell-2-0" class="cell"></td></tr>
44
+ <tr><td id="cell-0-1" class="cell"></td><td id="cell-1-1" class="cell"></td><td id="cell-2-1" class="cell"></td></tr>
45
+ <tr><td id="cell-0-2" class="cell"></td><td id="cell-1-2" class="cell"></td><td id="cell-2-2" class="cell"></td></tr>
46
+ </table>
47
+
48
+ <script type="text/javascript" charset="utf-8" src="mootools-1.2.4-core-nc.js"></script>
49
+ <script type="text/javascript" charset="utf-8" src="tictactoe.js"></script>
50
+ </body>
51
+ </html>
@@ -0,0 +1,130 @@
1
+ // Author: Jordan Fowler (TheBreeze)
2
+
3
+ var TicTacToe = new Class({
4
+ wins: 0,
5
+ loses: 0,
6
+ draws: 0,
7
+ methodMap: {
8
+ 'queued': 'onQueued',
9
+ 'start': 'onStart',
10
+ 'turn': 'onTurn',
11
+ 'move': 'onMove',
12
+ 'game_over': 'onGameOver',
13
+ 'win': 'onWin',
14
+ 'loss': 'onLoss',
15
+ 'draw': 'onDraw',
16
+ 'user_count': 'onUserCount'
17
+ },
18
+
19
+ initialize: function() {
20
+ if (TicTacToe.connection == null) {
21
+ TicTacToe.connection = new WebSocket('ws://localhost:8000/tictactoe');
22
+ };
23
+
24
+ TicTacToe.connection.onopen = this.join.bind(this);
25
+ TicTacToe.connection.onmessage = this.onMessage.bind(this);
26
+ TicTacToe.connection.onclose = this.onGameOver.bind(this);
27
+
28
+ this.setGameStats();
29
+ },
30
+
31
+ onMessage: function(event) {
32
+ var command = JSON.decode(event.data);
33
+
34
+ console.log('[RCV] ' + command.msg);
35
+
36
+ this[this.methodMap[command.msg]].call(this, command);
37
+ },
38
+
39
+ message: function(msg, options) {
40
+ var command = JSON.encode({msg: msg, data: options});
41
+
42
+ console.log('[SENT] ' + msg);
43
+
44
+ TicTacToe.connection.send(command);
45
+ },
46
+
47
+ setStatus: function(status) {
48
+ $('status').set('text', status);
49
+ },
50
+
51
+ setGameStats: function() {
52
+ $('game-stats').set('text', 'Wins: '+this.wins+' / Losses: '+this.wins+' / Draws: '+this.draws);
53
+ },
54
+
55
+ setUserCount: function(userCount) {
56
+ $('user-count').set('text', 'Number of players: ' + userCount);
57
+ },
58
+
59
+ join: function(event) {
60
+ this.message('join');
61
+
62
+ this.setStatus('Connecting you to a game...');
63
+ },
64
+
65
+ reset: function() {
66
+ $$('.cell').set('text', '');
67
+
68
+ this.join();
69
+ },
70
+
71
+ onQueued: function(command) {
72
+ this.setStatus('Waiting for another player...');
73
+ },
74
+
75
+ onStart: function(command) {
76
+ this.setStatus('Game found! Their turn first...');
77
+ },
78
+
79
+ onTurn: function(command) {
80
+ this.setStatus('Your turn...');
81
+ },
82
+
83
+ onMove: function(command) {
84
+ $('cell-'+command.data.x+'-'+command.data.y).set('text', command.key);
85
+
86
+ this.setStatus('Their turn...');
87
+ },
88
+
89
+ move: function(x, y) {
90
+ this.message('move', {x: x, y: y});
91
+ },
92
+
93
+ onGameOver: function(command) {
94
+ this.setStatus('Game over.');
95
+ this.setGameStats();
96
+ this.reset();
97
+ },
98
+
99
+ onWin: function(command) {
100
+ this.wins += 1;
101
+ this.setStatus('Game over. You win!');
102
+ this.setGameStats();
103
+ },
104
+
105
+ onLoss: function(command) {
106
+ this.losses += 1;
107
+ this.setStatus('Game over. You lose!');
108
+ this.setGameStats();
109
+ },
110
+
111
+ onDraw: function(command) {
112
+ this.draws += 1;
113
+ this.setStatus('Game over. It was a draw!');
114
+ this.setGameStats();
115
+ },
116
+
117
+ onUserCount: function(command) {
118
+ this.setUserCount(command.data);
119
+ }
120
+ });
121
+
122
+ $$('.cell').addEvent('click', function(event) {
123
+ try {
124
+ currentGame.move($(this).get('id').split('-')[1], $(this).get('id').split('-')[2]);
125
+ } catch(error) {
126
+ alert('Please wait while we connect you to a game...');
127
+ }
128
+ });
129
+
130
+ currentGame = new TicTacToe();