diff options
-rw-r--r-- | .project | 18 | ||||
-rw-r--r-- | Procfile | 1 | ||||
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | package.json | 33 | ||||
-rw-r--r-- | views/channel.html | 28 | ||||
-rw-r--r-- | views/client.html | 83 | ||||
-rw-r--r-- | views/home.html | 31 | ||||
-rw-r--r-- | views/layout.html | 11 | ||||
-rw-r--r-- | webcastor.js | 216 |
9 files changed, 429 insertions, 0 deletions
diff --git a/.project b/.project new file mode 100644 index 0000000..45abfac --- /dev/null +++ b/.project | |||
@@ -0,0 +1,18 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <projectDescription> | ||
3 | <name>Webcastor</name> | ||
4 | <comment></comment> | ||
5 | <projects> | ||
6 | </projects> | ||
7 | <buildSpec> | ||
8 | <buildCommand> | ||
9 | <name>com.eclipsesource.jshint.ui.builder</name> | ||
10 | <arguments> | ||
11 | </arguments> | ||
12 | </buildCommand> | ||
13 | </buildSpec> | ||
14 | <natures> | ||
15 | <nature>org.nodeclipse.ui.NodeNature</nature> | ||
16 | <nature>org.eclipse.wst.jsdt.core.jsNature</nature> | ||
17 | </natures> | ||
18 | </projectDescription> | ||
diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..d1c50f6 --- /dev/null +++ b/Procfile | |||
@@ -0,0 +1 @@ | |||
web: node webcastor.js \ No newline at end of file | |||
@@ -1,2 +1,10 @@ | |||
1 | Webcastor | 1 | Webcastor |
2 | ========= | 2 | ========= |
3 | |||
4 | Webcastor is a simple websocket broadcaster based on socket.io and node.js. | ||
5 | |||
6 | When a broadcaster sends a message to a channel, it is broadcast to all other clients (including other broadcasters) connected to the channel. | ||
7 | |||
8 | Channels are created with a generated ID and an optional broadcaster password. | ||
9 | |||
10 | This application is currently running on [https://webcastor.herokuapp.com/](https://webcastor.herokuapp.com/). | ||
diff --git a/package.json b/package.json new file mode 100644 index 0000000..da6dad6 --- /dev/null +++ b/package.json | |||
@@ -0,0 +1,33 @@ | |||
1 | { | ||
2 | "name": "Webcastor", | ||
3 | "version": "0.1.0", | ||
4 | "description": "Webcastor", | ||
5 | "main": "webcastor.js", | ||
6 | "scripts": { | ||
7 | "test": "echo \"Error: no test specified! Configure in package.json\" && exit 1" | ||
8 | }, | ||
9 | "repository": "", | ||
10 | "keywords": [ | ||
11 | "node.js", | ||
12 | "eclipse", | ||
13 | "nodeclipse" | ||
14 | ], | ||
15 | "author": "", | ||
16 | "license": "MIT", | ||
17 | "readmeFilename": "README.md", | ||
18 | "dependencies": { | ||
19 | "body-parser": "^1.1.1", | ||
20 | "express": "^4.1.2", | ||
21 | "hogan-express": "^0.5.2", | ||
22 | "http": "0.0.0", | ||
23 | "logfmt": "^1.1.2", | ||
24 | "password-hash": "^1.2.2", | ||
25 | "redis": "^0.10.1", | ||
26 | "socket.io": "^0.9.16", | ||
27 | "socket.io-wildcard": "^0.1.1", | ||
28 | "url": "^0.10.1" | ||
29 | }, | ||
30 | "engines": { | ||
31 | "node": "0.10.x" | ||
32 | } | ||
33 | } | ||
diff --git a/views/channel.html b/views/channel.html new file mode 100644 index 0000000..a1c13b5 --- /dev/null +++ b/views/channel.html | |||
@@ -0,0 +1,28 @@ | |||
1 | <h2>Create a channel</h2> | ||
2 | |||
3 | <h3>Channel created with given password</h3> | ||
4 | |||
5 | <form> | ||
6 | <label for="channel">Channel ID</label> | ||
7 | <input type="text" value="{{channel}}" readonly id="channel"> | ||
8 | <br> | ||
9 | <label for="url">URL</label> | ||
10 | <input type="text" value="{{url}}" readonly id="url"> | ||
11 | </form> | ||
12 | |||
13 | <style type="text/css"> | ||
14 | label { | ||
15 | display: inline-block; | ||
16 | width: 100px; | ||
17 | } | ||
18 | </style> | ||
19 | |||
20 | <script type="text/javascript"> | ||
21 | channel.addEventListener("click", function(event) { | ||
22 | this.select(); | ||
23 | }); | ||
24 | |||
25 | url.addEventListener("click", function(event) { | ||
26 | this.select(); | ||
27 | }); | ||
28 | </script> | ||
diff --git a/views/client.html b/views/client.html new file mode 100644 index 0000000..c322042 --- /dev/null +++ b/views/client.html | |||
@@ -0,0 +1,83 @@ | |||
1 | <h2>Test client</h2> | ||
2 | |||
3 | <form> | ||
4 | <label for="channelField">Channel</label> | ||
5 | <input type="text" id="channelField"> | ||
6 | <label for="passwordField">Password (optional)</label> | ||
7 | <input type="password" id="passwordField"> | ||
8 | <input type="submit" value="Connect" id="connectButton"> | ||
9 | </form> | ||
10 | <br> | ||
11 | <form> | ||
12 | <label for="messageField">Message</label> | ||
13 | <input type="text" disabled id="messageField"> | ||
14 | <input type="submit" value="Send" disabled id="sendButton"> | ||
15 | </form> | ||
16 | |||
17 | <hr> | ||
18 | <span>Log</span> | ||
19 | <pre id="console"></pre> | ||
20 | |||
21 | <script src="/socket.io/socket.io.js"></script> | ||
22 | <script type="text/javascript"> | ||
23 | var console = document.getElementById("console"); | ||
24 | |||
25 | function println(str) { | ||
26 | console.innerHTML = str + "\n" + console.innerHTML; | ||
27 | } | ||
28 | |||
29 | function changeControlState(connected) { | ||
30 | socketConnected = connected; | ||
31 | channelField.disabled = connected; | ||
32 | passwordField.disabled = connected; | ||
33 | if (connected) { | ||
34 | connectButton.value = "Disconnect"; | ||
35 | } else { | ||
36 | connectButton.value = "Connect"; | ||
37 | } | ||
38 | |||
39 | messageField.disabled = !connected; | ||
40 | sendButton.disabled = !connected; | ||
41 | } | ||
42 | |||
43 | var socket; | ||
44 | var socketConnected = false; | ||
45 | |||
46 | function connectSocket(channel, password) { | ||
47 | socket = io.connect("/", { | ||
48 | "query" : "channel=" + channel + "&password=" + password, | ||
49 | "force new connection" : true | ||
50 | }); | ||
51 | |||
52 | socket.on("connect", function() { | ||
53 | changeControlState(true); | ||
54 | println("connected"); | ||
55 | }); | ||
56 | |||
57 | socket.on("disconnect", function() { | ||
58 | changeControlState(false); | ||
59 | println("disconnected"); | ||
60 | }); | ||
61 | |||
62 | socket.on("message", function(message) { | ||
63 | println(message); | ||
64 | }); | ||
65 | } | ||
66 | |||
67 | |||
68 | connectButton.addEventListener("click", function(event) { | ||
69 | event.preventDefault(); | ||
70 | if (socketConnected) { | ||
71 | socket.disconnect(); | ||
72 | } else { | ||
73 | connectSocket(channelField.value, passwordField.value); | ||
74 | } | ||
75 | }); | ||
76 | |||
77 | sendButton.addEventListener("click", function(event) { | ||
78 | event.preventDefault(); | ||
79 | socket.emit("message", messageField.value); | ||
80 | messageField.value = ""; | ||
81 | }); | ||
82 | |||
83 | </script> \ No newline at end of file | ||
diff --git a/views/home.html b/views/home.html new file mode 100644 index 0000000..f6fef09 --- /dev/null +++ b/views/home.html | |||
@@ -0,0 +1,31 @@ | |||
1 | <h2>Create a channel</h2> | ||
2 | |||
3 | <form method="post" action="/"> | ||
4 | <label for="passwordField">Password (optional)</label> | ||
5 | <input type="password" id="passwordField" name="password"> | ||
6 | <input type="submit" id="randomButton" value="Generate random password"> | ||
7 | <input type="submit" value="Create a new channel"> | ||
8 | </form> | ||
9 | |||
10 | <br> | ||
11 | <hr> | ||
12 | |||
13 | <a href="/client">Test client</a> - <a href="https://github.com/Pacien/Webcastor">Sources</a> | ||
14 | |||
15 | <script type="text/javascript"> | ||
16 | randomButton.addEventListener("click", function(event) { | ||
17 | event.preventDefault(); | ||
18 | |||
19 | var randomPassword = Math.random().toString(36).substr(2, 10); | ||
20 | |||
21 | passwordField.type = "text"; | ||
22 | passwordField.value = randomPassword; | ||
23 | }); | ||
24 | |||
25 | passwordField.addEventListener("input", function(event) { | ||
26 | if (passwordField.value.length <= 1) { | ||
27 | passwordField.type = "password"; | ||
28 | } | ||
29 | }); | ||
30 | |||
31 | </script> | ||
diff --git a/views/layout.html b/views/layout.html new file mode 100644 index 0000000..c929bc9 --- /dev/null +++ b/views/layout.html | |||
@@ -0,0 +1,11 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head> | ||
4 | <meta charset="UTF-8"> | ||
5 | <title>Webcastor</title> | ||
6 | </head> | ||
7 | <body> | ||
8 | <h1>Webcastor</h1> | ||
9 | {{{ yield }}} | ||
10 | </body> | ||
11 | </html> \ No newline at end of file | ||
diff --git a/webcastor.js b/webcastor.js new file mode 100644 index 0000000..67b96d3 --- /dev/null +++ b/webcastor.js | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * This file is part of Webcastor <https://github.com/Pacien/Webcastor>. | ||
3 | |||
4 | * Webcastor is free software: you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation, either version 3 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | |||
9 | * Webcastor is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | |||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with Webcastor. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||