Browse Source

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
websocket
Rohan Sircar 4 years ago
parent
commit
2b3d6009f1
  1. 10
      package.json
  2. 21
      src/main/frontend/chat/main.ts
  3. 4
      src/main/frontend/chat/model/ChatModelHelper.ts
  4. 26
      src/main/frontend/chat/view/ChatView.ts
  5. 20
      src/main/frontend/chat/view/ChatViewDeps.ts
  6. 10
      src/main/frontend/common/dto/ChatMessageDTO.ts
  7. 50
      src/main/frontend/common/dto/MessageCipherDTO.ts
  8. 2
      src/main/java/org/ros/chatto/websocket/WebSocketConfig.java
  9. 24
      src/main/java/org/ros/chatto/websocket/WebSocketController.java
  10. 106
      yarn.lock

10
package.json

@ -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,10 +59,11 @@
"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",
"watch:admin": "watchify src/main/frontend/admin/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o src/main/resources/static/js/adminBundle.js"
}
}
}

21
src/main/frontend/chat/main.ts

@ -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);

4
src/main/frontend/chat/model/ChatModelHelper.ts

@ -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

26
src/main/frontend/chat/view/ChatView.ts

@ -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 {

20
src/main/frontend/chat/view/ChatViewDeps.ts

@ -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;
}

10
src/main/frontend/common/dto/ChatMessageDTO.ts

@ -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;
}

50
src/main/frontend/common/dto/MessageCipherDTO.ts

@ -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;
}

2
src/main/java/org/ros/chatto/websocket/WebSocketConfig.java

@ -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();
}

24
src/main/java/org/ros/chatto/websocket/WebSocketController.java

@ -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

@ -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=
Loading…
Cancel
Save