First integration of websocket into chat

Added sockjs and stompjs via yarn
Added websocket code to chat code
New endpoint for chat
New endpoint for ping
This commit is contained in:
Rohan Sircar 2020-08-07 12:24:20 +05:30
parent 21fa7b5e64
commit 2b3d6009f1
10 changed files with 103 additions and 170 deletions

View File

@ -1,5 +1,6 @@
{
"dependencies": {
"@stomp/stompjs": "^5.4.4",
"@types/bootbox": "^5.2.0",
"@types/datatables.net": "^1.10.19",
"@types/datatables.net-buttons": "^1.4.3",
@ -8,6 +9,7 @@
"@types/jquery": "^3.3.31",
"@types/markdown-it": "^0.0.9",
"@types/sjcl": "^1.0.29",
"@types/sockjs-client": "^1.1.1",
"@types/sprintf-js": "^1.1.2",
"alertifyjs": "^1.12.0",
"bootbox": "^5.4.0",
@ -25,8 +27,7 @@
"promise-worker": "^2.0.1",
"sjcl": "^1.0.8",
"sockjs-client": "^1.5.0",
"sprintf-js": "^1.1.2",
"stompjs": "^2.3.3"
"sprintf-js": "^1.1.2"
},
"devDependencies": {
"browserify": "^16.5.0",
@ -58,7 +59,8 @@
"depends": [
"@types/jquery"
]
}
},
"sockjs-client": "global:SockJS"
},
"scripts": {
"watch": "watchify src/main/frontend/chat/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o src/main/resources/static/js/bundle.js",

View File

@ -19,9 +19,29 @@ import { UserView } from "./view/UserView";
import { UserViewDeps } from "./view/UserViewDeps";
import { ActiveUserViewModel } from "./viewmodel/ActiveUserViewModel";
import moment = require("moment");
import SockJS from "sockjs-client";
import { Client } from "@stomp/stompjs";
// log.setLevel("TRACE");
const chatSocket = new SockJS("/chat");
const chatStompClient = new Client();
chatStompClient.webSocketFactory = () => chatSocket;
chatStompClient.activate();
const pingSocket = new SockJS("/ping");
const pingStompClient = new Client();
pingStompClient.webSocketFactory = () => pingSocket;
pingStompClient.activate();
pingStompClient.onConnect = () => {
pingStompClient.publish({ destination: "/app/ping" });
pingStompClient.subscribe("/user/queue/ping", (message) => {
log.debug(message);
log.debug(message.body);
});
};
const usersListElement = document.getElementById("contacts-box");
const userSearchButton = document.getElementById("user-search");
const userSearchInputElement = document.getElementById(
@ -51,6 +71,7 @@ const cvDeps: ChatViewDeps = {
encryptionService: encryptionService,
notificationService: ns,
userModel: userModel,
chatStompClient: chatStompClient,
};
const chatView = new ChatView(cvDeps);
chatModel.attach(chatView);

View File

@ -88,7 +88,7 @@ export class ChatModelHelper {
const vm = new ChatMessageViewModel();
vm.fromUser = chatMessageDTO.fromUser;
vm.toUser = chatMessageDTO.toUser;
vm.messageTime = chatMessageDTO.messageTime;
vm.messageTime = new Date(chatMessageDTO.messageTime);
vm.message = await this._encryptionService.decryptAsPromise(
passphrase,
chatMessageDTO.messageCipher
@ -106,7 +106,7 @@ export class ChatModelHelper {
// vm.messageTime = chatMessageDTO.messageTime;
chatMessageDTO.messageTime == null
? log.error("Message time somehow null")
: (vm.messageTime = chatMessageDTO.messageTime);
: (vm.messageTime = new Date(chatMessageDTO.messageTime));
vm.message = this._encryptionService.decrypt(
passphrase,
chatMessageDTO.messageCipher

View File

@ -27,6 +27,7 @@ export class ChatView implements Observer<ChatMessageViewModel> {
private readonly _encryptionService: EncryptionService;
private readonly _notificationService: NotificationService;
private readonly _userModel: UserModel;
private readonly _deps: ChatViewDeps;
constructor(deps: ChatViewDeps) {
this._messageContainer = deps.messageContainer;
@ -37,8 +38,19 @@ export class ChatView implements Observer<ChatMessageViewModel> {
this._encryptionService = deps.encryptionService;
this._notificationService = deps.notificationService;
this._userModel = deps.userModel;
this._deps = deps;
this._initEventListeners();
this._deps.chatStompClient.onConnect = () => {
this._deps.chatStompClient.subscribe("/user/queue/reply", (reply) => {
const message = JSON.parse(reply.body) as ChatMessageDTO;
log.debug(
message,
this._encryptionService.decrypt("password", message.messageCipher)
);
});
};
$(document).ready(function () {
$("#action_menu_btn").click(function () {
$(".action_menu").toggle();
@ -181,7 +193,7 @@ export class ChatView implements Observer<ChatMessageViewModel> {
};
this.update({ data: new Array(context), op: "new" });
this._userModel.updateLastActive(contactName, msgTime)
this._userModel.updateLastActive(contactName, msgTime);
this._userModel.notify();
let messageCipher: MessageCipherDTO = this._encryptionService.encrypt(
@ -194,7 +206,17 @@ export class ChatView implements Observer<ChatMessageViewModel> {
messageCipher: messageCipher,
messageTime: msgTime.toISOString(),
};
this._sendMessageAJAX(chatMessageDTO);
// this._sendMessageAJAX(chatMessageDTO);
this._sendMessageWS(chatMessageDTO);
}
private _sendMessageWS(chatMessageDTO: ChatMessageDTO): void {
// if (this._deps.chatStompClinet.connected) {
this._deps.chatStompClient.publish({
body: JSON.stringify(chatMessageDTO),
destination: "/app/chat",
});
// }
}
private _sendMessageAJAX(chatMessageDTO: any): void {

View File

@ -4,14 +4,16 @@ import { MarkDownService } from "../../common/service/MarkDownService";
import { EncryptionService } from "../../common/service/EncryptionService";
import { NotificationService } from "../../common/service/NotificationService";
import { UserModel } from "../model/UserModel";
import { Client } from "@stomp/stompjs";
export interface ChatViewDeps {
chatModel: ChatModel;
messageContainer: HTMLElement;
messageSendTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
messageReceiveTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
markdownService: MarkDownService;
encryptionService: EncryptionService;
notificationService: NotificationService;
userModel: UserModel
chatModel: ChatModel;
messageContainer: HTMLElement;
messageSendTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
messageReceiveTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
markdownService: MarkDownService;
encryptionService: EncryptionService;
notificationService: NotificationService;
userModel: UserModel;
chatStompClient: Client;
}

View File

@ -1,8 +1,8 @@
import { MessageCipherDTO } from "./MessageCipherDTO";
export class ChatMessageDTO {
public toUser: string = "";
public fromUser: string = "";
public messageCipher!: MessageCipherDTO;
public messageTime: Date = new Date();
export interface ChatMessageDTO {
toUser: string;
fromUser: string;
messageCipher: MessageCipherDTO;
messageTime: string;
}

View File

@ -1,40 +1,12 @@
// export class MessageCipherDTO {
// // iv!: string;
// // v!: number;
// // iterations!: number;
// // keySize!: number;
// // tagSize!: number;
// // mode!: string;
// // adata!: string;
// // cipher!: string;
// // salt!: string;
// // cipherText!: string;
// iv!: string;
// v!: number;
// iter!: number;
// ks!: number;
// ts!: number;
// mode!: string;
// adata!: string;
// cipher!: string;
// salt!: string;
// ct!: string;
// // public toMessageCipherDTO {
// // }
// }
export interface MessageCipherDTO {
iv: string,
v: number,
iter: number,
ks: number,
ts: number,
mode: string,
adata: string,
cipher: string,
salt: string,
ct: string,
iv: string;
v: number;
iter: number;
ks: number;
ts: number;
mode: string;
adata: string;
cipher: string;
salt: string;
ct: string;
}

View File

@ -18,6 +18,8 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ping");
registry.addEndpoint("/ping").withSockJS();
registry.addEndpoint("/chat");
registry.addEndpoint("/chat").withSockJS();
}

View File

@ -1,8 +1,10 @@
package org.ros.chatto.websocket;
import java.security.Principal;
import javax.validation.Valid;
import org.ros.chatto.model.ChatMessage;
import org.ros.chatto.dto.ChatMessageDTO;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessagingTemplate;
@ -17,21 +19,17 @@ public class WebSocketController {
private final SimpMessagingTemplate smt;
@MessageMapping("/chat2")
// @SendTo("/topic/messages")
// @SendToUser("/queue/reply")
public void send2(@Payload final Message message) throws Exception {
smt.convertAndSendToUser(message.getTo(), "/queue/reply", message);
// return message;
@MessageMapping("/ping")
public void send2(Principal principal) throws Exception {
smt.convertAndSendToUser(principal.getName(), "/queue/ping", "pong");
}
@MessageMapping("/chat")
// @SendTo("/topic/messages")
// @SendToUser("/queue/reply")
public void send(@Valid final ChatMessage message) throws Exception {
smt.convertAndSendToUser(message.getToUser().getUserName(),
"/queue/reply", message);
// return message;
public void send(@Valid @Payload final ChatMessageDTO message)
throws Exception {
smt.convertAndSendToUser(message.getFromUser(), "/queue/reply",
message);
smt.convertAndSendToUser(message.getToUser(), "/queue/reply", message);
}
@GetMapping("/ws")

106
yarn.lock
View File

@ -2,6 +2,11 @@
# yarn lockfile v1
"@stomp/stompjs@^5.4.4":
version "5.4.4"
resolved "https://registry.yarnpkg.com/@stomp/stompjs/-/stompjs-5.4.4.tgz#f51d2edf9a00fac645dde3a494738d96ca17e5aa"
integrity sha512-RIzQ7MLRSJLUpTHcje1ZclnHH982amJSKC9bDxGO0wyu5OF9ROuuiLf7TxKxo1zUu7lGEYNedg9SEi87uMWDqg==
"@types/bootbox@^5.2.0":
version "5.2.0"
resolved "https://registry.yarnpkg.com/@types/bootbox/-/bootbox-5.2.0.tgz#0e51344914dbe2fbb5c720b3bc2797c467d2115a"
@ -75,6 +80,11 @@
resolved "https://registry.yarnpkg.com/@types/sjcl/-/sjcl-1.0.29.tgz#bd154ee15421fe24be2db4a20322f38069c1ca71"
integrity sha512-gP9M7Oq4xAoDpuueWHeOTasccV4K6iFBEBPbR0tXejKT/e/Gkla0XcJ9REmgSCICt6y8/ubcvXFtiZ4ZLQ6BKA==
"@types/sockjs-client@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/sockjs-client/-/sockjs-client-1.1.1.tgz#1ef133b5a79d51447a93ce16164706c0164b5548"
integrity sha512-DaTdN4kfPNxu0otmQlxhmYeCjtY8cHmJsU6LqiFOrhytIkx8Txq06PwAWYzha7nMkEyju44a3NDpqCKiHn/NZQ==
"@types/sprintf-js@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@types/sprintf-js/-/sprintf-js-1.1.2.tgz#a4fcb84c7344f39f70dc4eec0e1e7f10a48597a3"
@ -839,14 +849,6 @@ currently-unhandled@^0.4.1:
dependencies:
array-find-index "^1.0.1"
d@1, d@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
dependencies:
es5-ext "^0.10.50"
type "^1.0.1"
dash-ast@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-1.0.0.tgz#12029ba5fb2f8aa6f0a861795b23c1b4b6c27d37"
@ -1025,32 +1027,6 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"
es5-ext@^0.10.35, es5-ext@^0.10.50:
version "0.10.53"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
dependencies:
es6-iterator "~2.0.3"
es6-symbol "~3.1.3"
next-tick "~1.0.0"
es6-iterator@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
dependencies:
d "1"
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
es6-symbol@^3.1.1, es6-symbol@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
dependencies:
d "^1.0.1"
ext "^1.1.2"
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
@ -1153,13 +1129,6 @@ exposify@~0.5.0:
through2 "~0.4.0"
transformify "~0.1.1"
ext@^1.1.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==
dependencies:
type "^2.0.0"
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@ -1819,11 +1788,6 @@ is-regexp@^1.0.0:
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
is-typedarray@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
@ -2171,11 +2135,6 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nan@^2.14.0:
version "2.14.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@ -2198,11 +2157,6 @@ neo-async@^2.6.0:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
next-tick@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
nopt@~3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
@ -2907,13 +2861,6 @@ static-extend@^0.1.1:
define-property "^0.2.5"
object-copy "^0.1.0"
stompjs@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/stompjs/-/stompjs-2.3.3.tgz#34178ac7bb8ee294cc5d554ad8b50f7f5459fd8e"
integrity sha1-NBeKx7uO4pTMXVVK2LUPf1RZ/Y4=
optionalDependencies:
websocket latest
stream-browserify@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
@ -3132,23 +3079,6 @@ tty-browserify@0.0.1:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"
integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==
type@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
type@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3"
integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==
typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
dependencies:
is-typedarray "^1.0.0"
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@ -3312,17 +3242,6 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
websocket@latest:
version "1.0.31"
resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.31.tgz#e5d0f16c3340ed87670e489ecae6144c79358730"
integrity sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==
dependencies:
debug "^2.2.0"
es5-ext "^0.10.50"
nan "^2.14.0"
typedarray-to-buffer "^3.1.5"
yaeti "^0.0.6"
which@^1.2.14, which@~1.3.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@ -3351,8 +3270,3 @@ xtend@~2.1.1:
integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os=
dependencies:
object-keys "~0.4.0"
yaeti@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577"
integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=