Add some web socket goodness.
This commit is contained in:
parent
04d90b7c7a
commit
74b370f19b
4 changed files with 73 additions and 5 deletions
25
public/chat.js
Normal file
25
public/chat.js
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
function sendMessage()
|
||||||
|
{
|
||||||
|
var msg = document.getElementById("inputLine")
|
||||||
|
socket.send(msg.value);
|
||||||
|
msg.value = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect(room, name)
|
||||||
|
{
|
||||||
|
socket = new WebSocket("ws://127.0.0.1:8080/ws?room="+encodeURIComponent(room)+"&name="+encodeURIComponent(name));
|
||||||
|
|
||||||
|
socket.onmessage = function(message) {
|
||||||
|
var history = document.getElementById("history");
|
||||||
|
var previous = history.innerHTML.trim();
|
||||||
|
if (previous.length) previous = previous + "\n";
|
||||||
|
history.innerHTML = previous + message.data;
|
||||||
|
history.scrollTop = history.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.onclose = function() {
|
||||||
|
console.log("socket closed - reconnecting...");
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
7
public/main.css
Normal file
7
public/main.css
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
textarea, input {
|
||||||
|
width: 40em;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
36
source/app.d
36
source/app.d
|
|
@ -19,10 +19,21 @@ import vibe.d;
|
||||||
|
|
||||||
final class Room {
|
final class Room {
|
||||||
string[] messages;
|
string[] messages;
|
||||||
|
ManualEvent messageEvent;
|
||||||
|
|
||||||
|
this() {
|
||||||
|
messageEvent = createManualEvent();
|
||||||
|
}
|
||||||
|
|
||||||
void addMessage(string nick, string message) {
|
void addMessage(string nick, string message) {
|
||||||
messages ~= nick ~ ": " ~ message;
|
messages ~= nick ~ ": " ~ message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waitForMessage(size_t next_message) {
|
||||||
|
while (messages.length <= next_message) {
|
||||||
|
messageEvent.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class WebChat {
|
final class WebChat {
|
||||||
|
|
@ -51,6 +62,29 @@ final class WebChat {
|
||||||
redirect("room?room=" ~ room.urlEncode ~ "&nick=" ~ nick.urlEncode);
|
redirect("room?room=" ~ room.urlEncode ~ "&nick=" ~ nick.urlEncode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /ws?room=...&nick=...
|
||||||
|
void getWS(string room, string nick, scope WebSocket socket) {
|
||||||
|
auto r = getOrCreateRoom(room);
|
||||||
|
auto writer = runTask({
|
||||||
|
auto next_message = r.messages.length;
|
||||||
|
while (socket.connected) {
|
||||||
|
while (next_message < r.messages.length) {
|
||||||
|
socket.send(r.messages[next_message++]);
|
||||||
|
}
|
||||||
|
r.waitForMessage(next_message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
while (socket.waitForData) {
|
||||||
|
auto message = socket.receiveText();
|
||||||
|
if (message.length) {
|
||||||
|
r.addMessage(nick, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.join();
|
||||||
|
}
|
||||||
|
|
||||||
private Room getOrCreateRoom(string room) {
|
private Room getOrCreateRoom(string room) {
|
||||||
if (auto pr = room in rooms) return *pr;
|
if (auto pr = room in rooms) return *pr;
|
||||||
return rooms[room] = new Room;
|
return rooms[room] = new Room;
|
||||||
|
|
@ -67,7 +101,7 @@ shared static this()
|
||||||
|
|
||||||
auto settings = new HTTPServerSettings;
|
auto settings = new HTTPServerSettings;
|
||||||
settings.port = 8083;
|
settings.port = 8083;
|
||||||
settings.bindAddresses = ["::1", "127.0.0.1"];
|
// settings.bindAddresses = ["::", "0.0.0.0"];
|
||||||
listenHTTP(settings, router);
|
listenHTTP(settings, router);
|
||||||
|
|
||||||
logInfo("Please open http://127.0.0.1:%d/ in your browser.".format(settings.port));
|
logInfo("Please open http://127.0.0.1:%d/ in your browser.".format(settings.port));
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
doctype html
|
doctype html
|
||||||
html
|
html
|
||||||
head
|
head
|
||||||
|
|
||||||
title #{room} - Webchat
|
title #{room} - Webchat
|
||||||
style.
|
style(type="text/css", src="main.css")
|
||||||
textarea, input { width: 100%; }
|
|
||||||
textarea { resize: vertical; }
|
|
||||||
body
|
body
|
||||||
|
- import vibe.data.json;
|
||||||
|
script(src="chat.js")
|
||||||
|
script connect(#{Json(room)}, #{Json(nick)})
|
||||||
h1 Room '#{room}'
|
h1 Room '#{room}'
|
||||||
textarea#history(rows=20, readonly=true)
|
textarea#history(rows=20, readonly=true)
|
||||||
- foreach (m; messages)
|
- foreach (m; messages)
|
||||||
|= m
|
|= m
|
||||||
|
|
||||||
form(action="room", method="POST")
|
form(action="room", method="POST", autocomplete="off", onsubmit="return sendMessage()")
|
||||||
input(type="hidden", name="room", value=room)
|
input(type="hidden", name="room", value=room)
|
||||||
input(type="hidden", name="nick", value=nick)
|
input(type="hidden", name="nick", value=nick)
|
||||||
input#inputLine(type="text", name="message", autofocus=true)
|
input#inputLine(type="text", name="message", autofocus=true)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue