Adding semi working chat implementation for channels.
parent
2e7422eede
commit
ca4e032dd6
|
@ -30,5 +30,6 @@ dependencies {
|
|||
compile('org.webjars:bootstrap:3.3.7-1')
|
||||
compile('org.webjars:jquery:3.2.1')
|
||||
compile('org.webjars:bootbox:4.4.0')
|
||||
compile('org.webjars:jquery:3.2.1')
|
||||
testCompile('org.springframework.boot:spring-boot-starter-test')
|
||||
}
|
||||
|
|
|
@ -1,13 +1,46 @@
|
|||
package pl.polgrabiat.websockets.chat.websocketschat.handlers;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import pl.polgrabiat.websockets.chat.websocketschat.dto.ChannelCtx;
|
||||
import pl.polgrabiat.websockets.chat.websocketschat.dto.GlobalCtx;
|
||||
import pl.polgrabiat.websockets.chat.websocketschat.dto.UserCtx;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class JoinCommandHandler implements SessionCommandHandler {
|
||||
|
||||
private static final Logger lg = LoggerFactory.getLogger(JoinCommandHandler.class);
|
||||
|
||||
@Override
|
||||
public boolean handleCommand(GlobalCtx globalCtx, WebSocketSession session, String payload, String command, String data) throws IOException {
|
||||
return false;
|
||||
StringTokenizer tokenizer = new StringTokenizer(data);
|
||||
String destination = tokenizer.nextToken().trim();
|
||||
|
||||
ChannelCtx channelCtx = globalCtx.getChannels().get(destination);
|
||||
if (channelCtx == null) {
|
||||
channelCtx = new ChannelCtx();
|
||||
channelCtx.setName(destination);
|
||||
globalCtx.getChannels().put(destination, channelCtx);
|
||||
}
|
||||
|
||||
UserCtx userCtx = globalCtx.getUserSessions().get(session);
|
||||
channelCtx.getUsers().add(userCtx);
|
||||
|
||||
for (UserCtx user : channelCtx.getUsers()) {
|
||||
try {
|
||||
sendMessage(user.getSession(), globalCtx,
|
||||
destination,
|
||||
"PRIVMSG " + channelCtx.getName() + " "
|
||||
+ user.getNick() + " has "
|
||||
+ " joined the channel");
|
||||
} catch (RuntimeException e) {
|
||||
lg.error("Error while sending a message", e);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public class NickCommandHandler implements SessionCommandHandler {
|
|||
String nick = tokenizer.nextToken();
|
||||
|
||||
if (nick.equals(globalCtx.getUserSessions().get(session).getNick())) {
|
||||
sendMessage(session,globalCtx,403, "MSG nick already used");
|
||||
sendMessage(session,globalCtx, globalCtx.getServerName(),"MSG nick already used");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ import java.io.IOException;
|
|||
public class PingMessageHandler implements SessionCommandHandler {
|
||||
@Override
|
||||
public boolean handleCommand(GlobalCtx globalCtx, WebSocketSession session, String payload, String command, String data) throws IOException {
|
||||
sendMessage(session,globalCtx,403, "MSG PING message is not accepted from the client-side");
|
||||
sendMessage(session,globalCtx, globalCtx.getUserSessions().get(session).getNick(),
|
||||
"MSG PING message is not accepted from the client-side");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package pl.polgrabiat.websockets.chat.websocketschat.handlers;
|
||||
|
||||
import org.apache.catalina.User;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import pl.polgrabiat.websockets.chat.websocketschat.dto.ChannelCtx;
|
||||
import pl.polgrabiat.websockets.chat.websocketschat.dto.GlobalCtx;
|
||||
|
@ -20,21 +19,21 @@ public class PrivMessageHandler implements SessionCommandHandler {
|
|||
ChannelCtx channel = globalCtx.getChannels().get(destination);
|
||||
if (channel == null) {
|
||||
sendMessage(session,
|
||||
globalCtx, 404, "MSG invalid destination");
|
||||
globalCtx, destination,"MSG invalid destination");
|
||||
return true;
|
||||
}
|
||||
|
||||
UserCtx userCtx = globalCtx.getUserSessions().get(session);
|
||||
|
||||
if (!channel.getUsers().contains(userCtx)) {
|
||||
sendMessage(session, globalCtx, 403, "MSG You are not the member of this channel");
|
||||
sendMessage(session, globalCtx, destination, "MSG You are not the member of this channel");
|
||||
return true;
|
||||
}
|
||||
|
||||
// sending to other users
|
||||
|
||||
for (UserCtx user : channel.getUsers()) {
|
||||
sendMessage(user.getSession(), globalCtx, 200, payload);
|
||||
sendMessage(user.getSession(), globalCtx, destination, payload);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -42,15 +41,16 @@ public class PrivMessageHandler implements SessionCommandHandler {
|
|||
} else {
|
||||
// user
|
||||
|
||||
|
||||
UserCtx userCtx = globalCtx.getUserSessions().get(destination);
|
||||
if (userCtx == null) {
|
||||
sendMessage(session,
|
||||
globalCtx, 404, "MSG invalid destination");
|
||||
globalCtx, destination,"MSG invalid destination");
|
||||
return true;
|
||||
}
|
||||
|
||||
sendMessage(userCtx.getSession(),
|
||||
globalCtx, 200, payload);
|
||||
globalCtx, destination, payload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -9,11 +9,10 @@ import java.io.IOException;
|
|||
public interface SessionCommandHandler {
|
||||
boolean handleCommand(GlobalCtx globalCtx, WebSocketSession session, String payload, String command, String data) throws IOException;
|
||||
|
||||
default void sendMessage(WebSocketSession session, GlobalCtx globalCtx, int responseCode, String data) throws IOException {
|
||||
session.sendMessage(new TextMessage(String.format(":%s %d %s %s",
|
||||
default void sendMessage(WebSocketSession session, GlobalCtx globalCtx, String source, String data) throws IOException {
|
||||
session.sendMessage(new TextMessage(String.format(":%s %s %s",
|
||||
globalCtx.getServerName(),
|
||||
responseCode,
|
||||
globalCtx.getUserSessions().get(session).getNick(),
|
||||
source,
|
||||
data)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public class UserCommandHandler implements SessionCommandHandler {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(GlobalCtx globalCtx, WebSocketSession session, String payload, String command, String data) throws IOException {
|
||||
StringTokenizer tokenizer = new StringTokenizer(data," ");
|
||||
StringTokenizer tokenizer = new StringTokenizer(data, " ");
|
||||
String userName = tokenizer.nextToken();
|
||||
String code1 = tokenizer.nextToken();
|
||||
if (!"0".equals(code1)) {
|
||||
|
@ -32,7 +32,9 @@ public class UserCommandHandler implements SessionCommandHandler {
|
|||
UserCtx userCtx = globalCtx.getUserSessions().get(session);
|
||||
|
||||
if (userCtx == null) {
|
||||
sendMessage(session, globalCtx, 403,
|
||||
sendMessage(session,
|
||||
globalCtx,
|
||||
globalCtx.getUserSessions().get(session).getNick(),
|
||||
"MSG you nead to select the nick");
|
||||
return true;
|
||||
}
|
||||
|
@ -40,7 +42,8 @@ public class UserCommandHandler implements SessionCommandHandler {
|
|||
userCtx.setUserName(userName);
|
||||
userCtx.setRealName(realName);
|
||||
|
||||
sendMessage(session, globalCtx, 200,
|
||||
sendMessage(session, globalCtx,
|
||||
globalCtx.getUserSessions().get(session).getNick(),
|
||||
"MSG OK");
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,38 @@
|
|||
function tabRef (destination) {
|
||||
if (destination.startsWith("#")) {
|
||||
return "c" + destination.substr(1);
|
||||
} else {
|
||||
return "u" + destination;
|
||||
}
|
||||
};
|
||||
|
||||
function IrcClient(sockJs, nick, userName, realName) {
|
||||
this.sockJs = sockJs;
|
||||
this.nick = nick;
|
||||
this.userName = userName;
|
||||
this.realName = realName;
|
||||
|
||||
this.sendMsg = function(msg) {
|
||||
this.sendMsg = function (msg) {
|
||||
console.log("OUT-MSG " + msg);
|
||||
this.sockJs.send(msg);
|
||||
};
|
||||
|
||||
this.sendNickMsg = function() {
|
||||
this.sendNickMsg = function () {
|
||||
this.sendMsg("NICK " + this.nick);
|
||||
};
|
||||
|
||||
this.sendUserMsg = function() {
|
||||
this.sendUserMsg = function () {
|
||||
this.sendMsg("USER " + this.userName + " 0 * :" + this.realName);
|
||||
};
|
||||
|
||||
this.sendPrivMsg = function (msg) {
|
||||
this.sendDestPrivMsg(this.selectedDestination(), msg);
|
||||
};
|
||||
|
||||
this.sendDestPrivMsg = function (dest, msg) {
|
||||
this.sendMsg("PRIVMSG " + dest + " " + msg);
|
||||
};
|
||||
|
||||
this.init = function () {
|
||||
this.sendNickMsg();
|
||||
this.sendUserMsg();
|
||||
|
@ -33,7 +49,7 @@ function IrcClient(sockJs, nick, userName, realName) {
|
|||
console.log("Socket closed");
|
||||
};
|
||||
|
||||
this.sendPongMsg = function(nr) {
|
||||
this.sendPongMsg = function (nr) {
|
||||
this.sendMsg("PONG :" + nr);
|
||||
};
|
||||
|
||||
|
@ -42,15 +58,78 @@ function IrcClient(sockJs, nick, userName, realName) {
|
|||
this.sendPongMsg(data);
|
||||
};
|
||||
|
||||
this.sockJs.onmessage = function (e) {
|
||||
console.log("Received message: " + e.data);
|
||||
var server = document.getElementById("server");
|
||||
var logRow = document.createElement("div");
|
||||
logRow.innerHTML = e.data;
|
||||
server.appendChild(logRow);
|
||||
if (e.data.startsWith("PING ")) {
|
||||
ircClientRef.handlePongMessage(e.data, e.data.substr(7));
|
||||
this.createTabEl = function (destination) {
|
||||
var tabs = $("#tabs");
|
||||
var liEl = $("<li/>");
|
||||
var aEl = $("<a/>");
|
||||
|
||||
aEl.attr("href", "#" + tabRef(destination));
|
||||
aEl.attr("data-toggle", "tab");
|
||||
aEl.html(destination);
|
||||
|
||||
|
||||
liEl.attr("id", "label-" + tabRef(destination));
|
||||
liEl.append(aEl);
|
||||
tabs.append(liEl);
|
||||
};
|
||||
|
||||
this.createTabContentEl = function (destination) {
|
||||
var tabsContent = $("#tabs-content");
|
||||
var divEl = $("<div />");
|
||||
divEl.addClass("tab-pane fade in");
|
||||
divEl.attr("id", tabRef(destination));
|
||||
tabRef(destination);
|
||||
|
||||
tabsContent.append(divEl);
|
||||
};
|
||||
|
||||
this.checkForDestElseCreate = function (destination) {
|
||||
var tabIdx = tabRef(destination);
|
||||
if ($("#label-" + tabIdx).length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ircClientRef.createTabEl(destination);
|
||||
ircClientRef.createTabContentEl(destination);
|
||||
};
|
||||
|
||||
this.displayDestinationMessage = function (destination, msg) {
|
||||
this.checkForDestElseCreate(destination);
|
||||
var server = $("#" + tabRef(destination));
|
||||
var logRow = $("<div/>");
|
||||
logRow.text(msg);
|
||||
server.append(logRow);
|
||||
return server;
|
||||
};
|
||||
|
||||
this.selectedDestination = function () {
|
||||
return $("#tabs").find("li.active").text();
|
||||
};
|
||||
|
||||
this.fetchDestination = function (data) {
|
||||
var preDestIdx = data.indexOf(" ");
|
||||
if (preDestIdx < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var destIdx = preDestIdx + 1;
|
||||
var preDataIdx = data.indexOf(" ", destIdx);
|
||||
return data.substr(destIdx, preDataIdx - destIdx);
|
||||
};
|
||||
|
||||
this.sockJs.onmessage = function (e) {
|
||||
var msg = e.data;
|
||||
if (msg.startsWith("PING ")) {
|
||||
ircClientRef.handlePongMessage(msg, msg.substr(7));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Received message: " + msg);
|
||||
var destination = ircClientRef.fetchDestination(e.data);
|
||||
var tabName = destination;
|
||||
console.log("Destination of the message: " + destination);
|
||||
|
||||
var server = ircClientRef.displayDestinationMessage(tabName, msg);
|
||||
};
|
||||
|
||||
};
|
|
@ -7,21 +7,22 @@
|
|||
<script type="application/javascript" src="/webjars/jquery/3.2.1/jquery.js"></script>
|
||||
<script type="application/javascript" src="/webjars/bootstrap/3.3.7-1/js/bootstrap.js"></script>
|
||||
<script type="application/javascript" src="/webjars/bootbox/4.4.0/bootbox.js"></script>
|
||||
<script type="application/javascript" src="/webjars/jquery/3.2.1/jquery.js"></script>
|
||||
<script type="application/javascript" src="index.js"></script>
|
||||
<script type="application/javascript" src="IrcClient.js"></script>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a data-toggle="tab" href="#server">Server</a></li>
|
||||
<ul id="tabs" class="nav nav-tabs">
|
||||
<li id="label-server" class="active"><a data-toggle="tab" href="#server">Server</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div id="tabs-content" class="tab-content">
|
||||
<div id="server" class="tab-pane fade in active">
|
||||
Contents
|
||||
SERVER
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input id="message" type="text" />
|
||||
<input class="form-control" id="message"/>
|
||||
</body>
|
||||
</html>
|
|
@ -28,7 +28,14 @@ window.onload = function () {
|
|||
var messageInput = document.getElementById("message");
|
||||
messageInput.onkeyup = function (e) {
|
||||
if (e.keyCode == 13) {
|
||||
sockJs.send(messageInput.value);
|
||||
var command = messageInput.value;
|
||||
if (command.startsWith("/")) {
|
||||
// special command
|
||||
window.ircClient.sendMsg(command.substr(1));
|
||||
} else {
|
||||
window.ircClient.sendPrivMsg(command);
|
||||
}
|
||||
$(messageInput).val("");
|
||||
}
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue