em-websocket-server 0.1.2 → 0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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();