Skip to content

Commit 6a6d33e

Browse files
committed
Merge branch 'socket-available-in-clients' of git://github.com/MarkBennett/start into MarkBennett-socket-available-in-clients
# By Mark Bennett # Via Mark Bennett * 'socket-available-in-clients' of git://github.com/MarkBennett/start: Cleaning up browser Socket tests. Test the exported start package. Refactor VM and browser Socket into seperate files. Create an HtmlSocket which can be used in the browser. Rename dart:io only Socket to IoSocket. Move server socket back into lib/src. Serialize messages to and from packets. Refactor Message to work with packets. Add basic tests of Socket. Make unittest a dev dependency. Make Socket available to clients. Conflicts: lib/src/socket.dart lib/start.dart pubspec.yaml
2 parents 467a3e3 + 70b9a78 commit 6a6d33e

13 files changed

+236
-40
lines changed

example/app.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ void main() {
1010
});
1111

1212
app.ws('/socket').listen((socket) {
13-
socket.on('ping').listen((data) {
14-
socket.send('pong');
13+
socket.on('connected').listen((data) {
14+
socket.send('ping');
1515
});
1616

1717
socket.on('pong').listen((data) {

example/web/scripts/script.dart

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import 'dart:html';
22
import 'dart:json';
33

4+
import 'package:start/socket.dart';
5+
46
main() {
5-
var ws = new WebSocket("ws://127.0.0.1:3000/socket");
7+
var socket = new Socket('ws://127.0.0.1:3000/socket');
68

7-
ws.onOpen.listen((a) {
8-
ws.send('ping');
9+
socket.onOpen.listen((a) {
10+
socket.send('connected');
911
});
1012

11-
ws.onClose.listen((c) {
13+
socket.onClose.listen((c) {
1214
print('[${c.code}] ${c.reason}');
1315
});
1416

15-
ws.onMessage.listen((m) {
16-
if (m.data == "pong") {
17-
ws.send('pong');
18-
}
17+
socket.on('ping').listen((data) {
18+
socket.send('pong');
1919
});
2020
}

lib/socket.dart

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'dart:html';
2+
import 'dart:async';
3+
4+
import 'src/socket_base.dart';
5+
6+
class Socket implements SocketBase {
7+
WebSocket _ws;
8+
9+
var _messageController = new StreamController();
10+
Stream _messages;
11+
12+
Socket(String url) {
13+
_messages = _messageController.stream.asBroadcastStream();
14+
_ws = new WebSocket(url);
15+
_ws.onMessage.listen((e) {
16+
var msg = new Message(e.data);
17+
_messageController.add(msg);
18+
});
19+
}
20+
21+
void send(String messageName, { data }) {
22+
var message = new Message(messageName, data);
23+
_ws.send(message.toPacket());
24+
}
25+
26+
Stream on(String messageName) {
27+
return _messages.where((msg) => msg.name == messageName);
28+
}
29+
30+
Stream get onOpen => _ws.onOpen;
31+
32+
Stream get onClose => _ws.onClose;
33+
34+
void close([int status, String reason]) {
35+
_ws.close(status, reason);
36+
}
37+
}

lib/src/message.dart

+19-10
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
part of start;
1+
library start_message;
2+
3+
import 'dart:json' as Json;
24

35
class Message {
4-
6+
57
String _name;
68
String get name => _name;
7-
9+
810
var _data;
911
get data => _data;
10-
11-
factory Message(String message) {
12+
13+
Message(this._name, [this._data]);
14+
15+
factory Message.fromPacket(String message) {
1216
if (message.isEmpty) {
1317
return new Message.empty();
1418
}
15-
19+
1620
List<String> parts = message.split(":");
1721
String name = parts.first;
1822
var data = null;
@@ -21,13 +25,18 @@ class Message {
2125
data = Json.parse(parts.sublist(1).join(":"));
2226
}
2327
}
24-
return new Message._internal(parts.first, data);
28+
return new Message(parts.first, data);
2529
}
26-
27-
Message._internal(this._name, this._data);
28-
30+
2931
Message.empty() {
3032
this._name = "";
3133
this._data = null;
3234
}
35+
36+
String toPacket() {
37+
if (_data == null) {
38+
return _name;
39+
}
40+
return "$_name:${Json.stringify(_data)}";
41+
}
3342
}

lib/src/socket.dart

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
part of start;
22

3-
class Socket {
3+
class Socket implements SocketBase {
44
WebSocket _ws;
55

66
var _messageController = new StreamController();
7-
Stream _messages = _messageController.stream;
7+
Stream _messages;
88

9-
Socket(WebSocket ws) {
10-
this._ws = ws;
9+
Socket(this._ws) {
10+
_messages = _messageController.stream.asBroadcastStream();
1111
_ws.listen((data) {
1212
var msg = new Message(data);
1313
_messageController.add(msg);
@@ -17,8 +17,9 @@ class Socket {
1717
});
1818
}
1919

20-
void send(Object message) {
21-
_ws.add(message);
20+
void send(String messageName, { data }) {
21+
var message = new Message(messageName, data);
22+
_ws.add(message.toPacket());
2223
}
2324

2425
Stream on(String messageName) {

lib/src/socket_base.dart

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
library start_socket;
2+
3+
import 'dart:async';
4+
5+
import 'message.dart';
6+
7+
export 'message.dart' show Message;
8+
9+
abstract class SocketBase {
10+
void send(String msg_name, { data });
11+
12+
Stream on(String message_name);
13+
14+
void close([int status, String reason]);
15+
16+
}

lib/start.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import 'dart:async';
55
import 'dart:json' as Json;
66
import 'dart:mirrors';
77

8+
import 'src/socket_base.dart';
9+
810
part 'src/route.dart';
911
part 'src/request.dart';
1012
part 'src/response.dart';
11-
part 'src/message.dart';
12-
part 'src/socket.dart';
1313
part 'src/server.dart';
1414
part 'src/mime_types.dart';
15+
part 'src/socket.dart';
1516

1617
Future<Server> start({ String public: 'web', String host: '127.0.0.1', int port: 80 }) {
1718
return new Server(public).listen(host, port);

test/browser_socket_test.dart

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
part of start_test;
2+
3+
socket_tests() {
4+
group("Socket", () {
5+
test("this should pass", () {
6+
expect(1, equals(1));
7+
});
8+
});
9+
}

test/message_test.dart

+49-11
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ part of start_test;
33
message_tests() {
44
group("Message,", () {
55
test("parses empty message", () {
6-
Message msg = new Message("");
6+
Message msg = new Message.fromPacket("");
77

88
expect(msg.name, equals(""));
99
expect(msg.data, equals(null));
1010
});
1111

1212
test("parses named message", () {
13-
Message msg = new Message("test");
13+
Message msg = new Message.fromPacket("test");
1414

1515
expect(msg.name, equals("test"));
1616
expect(msg.data, equals(null));
1717
});
1818

1919
test("parses named message with empty data", () {
20-
Message msg = new Message("test:");
20+
Message msg = new Message.fromPacket("test:");
2121

2222
expect(msg.name, equals("test"));
2323
expect(msg.data, equals(null));
@@ -28,55 +28,55 @@ message_tests() {
2828
"stuff":123,
2929
"other":"test"
3030
};
31-
Message msg = new Message("test:${stringify(data)}");
31+
Message msg = new Message.fromPacket("test:${stringify(data)}");
3232

3333
expect(msg.name, equals("test"));
3434
expect(msg.data, equals(data));
3535
});
3636

3737
test("parses named message with List for data", () {
3838
List data = [1, 2, 3];
39-
Message msg = new Message("test:${stringify(data)}");
39+
Message msg = new Message.fromPacket("test:${stringify(data)}");
4040

4141
expect(msg.name, equals("test"));
4242
expect(msg.data, equals(data));
4343
});
4444

4545
test("parses named message with bool for data", () {
4646
bool data = true;
47-
Message msg = new Message("test:${stringify(data)}");
47+
Message msg = new Message.fromPacket("test:${stringify(data)}");
4848

4949
expect(msg.name, equals("test"));
5050
expect(msg.data, equals(data));
5151
});
5252

5353
test("parses named message with String for data", () {
5454
String data = "abc123";
55-
Message msg = new Message("test:${stringify(data)}");
55+
Message msg = new Message.fromPacket("test:${stringify(data)}");
5656

5757
expect(msg.name, equals("test"));
5858
expect(msg.data, equals(data));
5959
});
6060

6161
test("parses named message with String containing colon for data", () {
6262
String data = "a:b:c";
63-
Message msg = new Message("test:${stringify(data)}");
63+
Message msg = new Message.fromPacket("test:${stringify(data)}");
6464

6565
expect(msg.name, equals("test"));
6666
expect(msg.data, equals(data));
6767
});
6868

6969
test("parses named message with int for data", () {
7070
int data = 123;
71-
Message msg = new Message("test:${stringify(data)}");
71+
Message msg = new Message.fromPacket("test:${stringify(data)}");
7272

7373
expect(msg.name, equals("test"));
7474
expect(msg.data, equals(data));
7575
});
7676

7777
test("parses named message with double for data", () {
7878
double data = 123.45;
79-
Message msg = new Message("test:${stringify(data)}");
79+
Message msg = new Message.fromPacket("test:${stringify(data)}");
8080

8181
expect(msg.name, equals("test"));
8282
expect(msg.data, equals(data));
@@ -87,10 +87,48 @@ message_tests() {
8787
"stuff":123,
8888
"other":"test"
8989
};
90-
Message msg = new Message(":${stringify(data)}");
90+
Message msg = new Message.fromPacket(":${stringify(data)}");
9191

9292
expect(msg.name, equals(""));
9393
expect(msg.data, equals(data));
9494
});
95+
96+
test("creating a new Message from just a name", () {
97+
Message msg = new Message("test");
98+
99+
expect(msg.name, equals("test"));
100+
expect(msg.data, isNull);
101+
});
102+
103+
test("creating a new Message from a name and data", () {
104+
Message msg = new Message("test", 123);
105+
106+
expect(msg.name, equals("test"));
107+
expect(msg.data, equals(123));
108+
});
109+
110+
test("a message can be serialized to a packet and back", () {
111+
Message original_msg = new Message("serial_test", {"bob":123});
112+
113+
Message decoded_msg = new Message.fromPacket(original_msg.toPacket());
114+
115+
expect(decoded_msg.name, equals(original_msg.name));
116+
expect(decoded_msg.data, equals(original_msg.data));
117+
});
118+
119+
test("a message without data can be serialized to a packet and back", () {
120+
Message original_msg = new Message("serial_test");
121+
122+
Message decoded_msg = new Message.fromPacket(original_msg.toPacket());
123+
124+
expect(decoded_msg.name, equals(original_msg.name));
125+
expect(decoded_msg.data, equals(original_msg.data));
126+
});
127+
128+
test("a message without data does not include the ':' in the packer", () {
129+
Message msg = new Message("test123");
130+
131+
expect(msg.toPacket(), equals("test123"));
132+
});
95133
});
96134
}

test/start_browser_test.dart

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library start_test;
2+
3+
import 'dart:json';
4+
import 'dart:html';
5+
6+
import 'package:unittest/unittest.dart';
7+
import 'package:unittest/mock.dart';
8+
import 'package:unittest/html_config.dart';
9+
import 'package:start/socket.dart';
10+
11+
part "message_test.dart";
12+
part "browser_socket_test.dart";
13+
14+
main() {
15+
useHtmlConfiguration();
16+
17+
message_tests();
18+
socket_tests();
19+
}

test/start_browser_test.html

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
3+
<html>
4+
<head>
5+
<title>test</title>
6+
</head>
7+
8+
<body>
9+
<p id="text"></p>
10+
<script type="application/dart" src="start_browser_test.dart"></script>
11+
<!-- for this next line to work, your pubspec.yaml file must have a dependency on 'browser' -->
12+
<script src="packages/browser/dart.js"></script>
13+
</body>
14+
</html>

0 commit comments

Comments
 (0)