Advertisement
Guest User

test

a guest
Aug 6th, 2016
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.12 KB | None | 0 0
  1. app.js
  2.  
  3. $(document).ready(function() {
  4.  
  5. /*
  6. Assigning element IDs to variables
  7. */
  8. var sendButton = $('#snd');
  9. var msg = $('#msg');
  10. var messages = $('#messages_list');
  11. var my_status = $('#my_status');
  12. var typing = $('#typing');
  13. var options = $('#attachment_options');
  14. var chat_window = $('#chat_window');
  15.  
  16. /*
  17. Prepare notification sound for playing
  18. */
  19. var notify_sound = new Howl({
  20. src: ['./assets/sounds/notify2.mp3'],
  21. volume: 1.0 //set to full volume
  22. });
  23.  
  24. /*
  25. Disabling Send button on page load
  26. */
  27. disable_button();
  28.  
  29. /*
  30. Setting up variables required for making the connection
  31. */
  32. var conn = new WebSocket('ws://192.168.0.100:3000'); //Change the ws address to your address
  33. var active = 0; //Variable to hold the current connection status
  34. var remoteAddress;
  35.  
  36. /*
  37. Opening the connection to the socket
  38. */
  39. conn.onopen = function(e) {
  40. my_status.addClass('i_am_online'); //Sets the user icon to green
  41. active = 1; //Sets to 1 to denote connection is open
  42. conn.send(JSON.stringify({
  43. action: 'getReady' //Fetching the remote address and messages of the current user
  44. }));
  45. };
  46.  
  47. /*
  48. Handling messages received
  49. */
  50. conn.onmessage = function(e) {
  51. var obj = JSON.parse(e.data);
  52. var type = obj.type;
  53. var userAddress = obj.ip;
  54.  
  55. var unreadableTimeStamp = parseInt(obj.times);
  56. /**
  57. * Preparing Human readable timestamp
  58. */
  59. var time = moment(unreadableTimeStamp).calendar(null, {
  60. sameDay: '[Today at] HH:mm',
  61. nextDay: '[Tomorrow]',
  62. nextWeek: 'dddd',
  63. lastDay: '[Yesterday at] HH:mm',
  64. lastWeek: '[Last] dddd',
  65. sameElse: 'DD/MM/YYYY'
  66. });
  67. /*
  68. Handling server responses
  69. */
  70. if(type == "getUserAddress") {
  71. remoteAddress = userAddress;
  72. }
  73. //else
  74. //if(type == "fetch_count") {
  75. // msg_fetched_count = obj.count;
  76. //}
  77. else
  78. if(type == "userJoin") {
  79. messages.append('<li class="user_connect"><p class="message">'+ obj.ip +' '+ obj.message +'</p></li>');
  80. }
  81. else
  82. if(type == "userLeft") {
  83. messages.append('<li class="user_disconnect"><p class="message">'+ obj.ip +' '+ obj.message +'</p></li>');
  84. }
  85. else
  86. if(type == "typingOn") {
  87. typing.html(obj.ip + obj.message).fadeIn('fast');
  88. }
  89. else
  90. if(type == "typingOff") {
  91. typing.html('').fadeOut('fast');
  92. }
  93. else
  94. if(type == "user"){
  95. if(userAddress == remoteAddress) {
  96. typing.html('').fadeOut('fast');
  97. messages.append('<li class="self" id="'+obj.id+'"><p class="message">'+ obj.message + '</p><p class="time">' + time +'</p></li><p class="username_self">' + userAddress + '</p>');
  98. }
  99. else {
  100. typing.html('').fadeOut('fast');
  101. messages.append('<li class="other" id="'+obj.id+'"><p class="message">' + obj.message + '</p><p class="time">' + time + '</p></li><p class="username_other">' + userAddress + '</p>');
  102. if(obj.play != "no") {
  103. notify_sound.play(); //Play sound for arriving messages only
  104. }
  105. }
  106. }
  107. //Scroll the window to top automatically on new message
  108. chat_window.animate({scrollTop: chat_window.get(0).scrollHeight}, 1000);
  109. };
  110.  
  111. /*
  112. Closing connection to socket
  113. */
  114. conn.onclose = function(e) {
  115. my_status.removeClass('i_am_online');
  116. active = 0;
  117. };
  118.  
  119.  
  120. /**
  121. * The following part manages the basic chat interface.
  122. * It handles primarily the DOM
  123. */
  124.  
  125.  
  126. /*
  127. Toggle the attachment container view
  128. */
  129. $('#attachment').click(function (e) {
  130. options.slideToggle("slow");
  131. $(this).toggleClass("option-active");
  132. e.stopPropagation();
  133. });
  134. options.click(function (e) {
  135. e.stopPropagation();//Prevent closing of container on click within it
  136. });
  137. $('body').click(function (e) {//Close container if click/tap on body is received
  138. options.slideUp();
  139. $('#attachment').removeClass("option-active");
  140. });
  141.  
  142.  
  143. /*
  144. Emergency Exit Procedure
  145. */
  146. $('#exit').click(function() {
  147. window.location.replace('http://www.google.com');
  148. });
  149.  
  150.  
  151. var isTyping = false;
  152. var timeout = undefined;
  153.  
  154. function timeoutFunction() {
  155. isTyping = false;
  156. conn.send(JSON.stringify({
  157. action: 'typing-ended'
  158. }));
  159. }
  160.  
  161. /*
  162. Preventing blank input and handling {user} is typing functionality6
  163. */
  164. msg.on('keyup', function(e) {
  165. if ('' != msg.val()) {
  166. enable_button(); //Enable send button if message content is not empty
  167. if(isTyping == false) {
  168. isTyping = true;
  169. conn.send(JSON.stringify({
  170. action: 'typing-started'
  171. }));
  172. timeout = setTimeout(timeoutFunction, 2000);
  173. }
  174. else {
  175. clearTimeout(timeout);
  176. timeout = setTimeout(timeoutFunction, 2000);
  177. }
  178.  
  179. }
  180. else{
  181. disable_button();
  182. }
  183.  
  184. });
  185.  
  186. /*
  187. Handling message sending
  188. */
  189. sendButton.click(function() {
  190. if (!sendButton.hasClass('active')) {
  191. return;
  192. }
  193. var thread = msg.val();
  194. //console.log(thread);
  195. if(active == 1) {
  196. conn.send(JSON.stringify({
  197. action: 'sending',
  198. msg: thread
  199. }));
  200. // empty message text area
  201. msg.val('');
  202. disable_button();
  203. }
  204. else {
  205. alert('There seems to be a problem with your connection!\nCheck your internet connection and reload the page.');
  206. }
  207. });
  208.  
  209. /*
  210. Load previous messages
  211. */
  212. chat_window.scroll(function() {
  213. var offset;
  214. var pos = chat_window.scrollTop();
  215. if (pos == 0){
  216. offset = messages.find('.self,.other').eq(0).attr("id");
  217. $('#load_previous').css('display', 'block');
  218. conn.send(JSON.stringify({
  219. action: 'load_older',
  220. start: offset
  221. }));
  222. }
  223. });
  224.  
  225. /*
  226. Enable button function
  227. */
  228. function enable_button() {
  229. sendButton.css('cursor', 'pointer').addClass('active');
  230. }
  231.  
  232. /*
  233. Disable button function
  234. */
  235. function disable_button() {
  236. sendButton.css('cursor', 'default').removeClass('active');
  237. }
  238.  
  239. });
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246. chat.php
  247.  
  248. <?php
  249.  
  250. namespace MyApp;
  251.  
  252. use Ratchet\MessageComponentInterface;
  253. use Ratchet\ConnectionInterface;
  254. use Emojione\Client;
  255. use Emojione\Ruleset;
  256. use \PDO;
  257. use \PDOException;
  258.  
  259. class Chat implements MessageComponentInterface {
  260. protected $clients;
  261. /**
  262. * @var \Emojione\Client
  263. */
  264. private $emojioneClient;
  265. private $dbh;
  266.  
  267. public function __construct() {
  268. $this->clients = new \SplObjectStorage;
  269. /**
  270. * Following for setting up conversion and display of native and ascii emojis
  271. */
  272. $this->emojioneClient = new Client(new Ruleset());
  273. $this->emojioneClient->imageType = 'png';
  274. $this->emojioneClient->imagePathPNG = './assets/png/';
  275. $this->emojioneClient->ascii = true;
  276. // Open connection to Database
  277. $this->connect();
  278. }
  279.  
  280.  
  281. public function onOpen(ConnectionInterface $conn) {
  282. // first, you are sending to all existing users message of 'new'
  283. foreach ($this->clients as $client) {
  284. $client->send(json_encode(array('ip' => $conn->remoteAddress, 'message' => 'online', 'type' => 'userJoin', 'times' => round(microtime(true) * 1000))));
  285. }
  286. // then,
  287. // Store the new connection to send messages to later
  288. $this->clients->attach($conn);
  289.  
  290. my_log("New connection! ({$conn->remoteAddress})");
  291. }
  292.  
  293.  
  294.  
  295. public function onMessage(ConnectionInterface $from, $msg) {
  296.  
  297. $data = $this->parseMessage($msg);
  298.  
  299. $numRecv = count($this->clients) - 1;
  300. my_log(sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
  301. , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'));
  302.  
  303.  
  304. if($data->action === "getReady") {
  305. foreach ($this->clients as $client) {
  306. if($from === $client) {
  307. $client->send(json_encode(array('ip' => $from->remoteAddress, 'type' => 'getUserAddress', 'times' => round(microtime(true) * 1000))));
  308. // Fetch messages here
  309. $encoded_JSON_Array = $this->fetchMessages();
  310. $decoded_JSON_Array = json_decode($encoded_JSON_Array, true);
  311.  
  312. foreach ($decoded_JSON_Array as $row) {
  313. $client->send(json_encode(array('id' => $row['id'], 'ip' => $row['ip'], 'message' => $this->parseEmojiToImage($row['message']), 'type' => $row['type'], 'times' => $row['times'], 'play' => 'no')));
  314. }
  315. }
  316. }
  317. }
  318. else
  319. if($data->action === "load_older") {
  320. foreach ($this->clients as $client) {
  321. if ($from === $client) {
  322. $offset = $data->start;
  323. $encoded_JSON_Array = $this->fetchMessages($offset);
  324. $decoded_JSON_Array = json_decode($encoded_JSON_Array, true);
  325.  
  326. foreach ($decoded_JSON_Array as $row) {
  327. $client->send(json_encode(array('id' => $row['id'], 'ip' => $row['ip'], 'message' => $this->parseEmojiToImage($row['message']), 'type' => $row['type'], 'times' => $row['times'], 'play' => 'no')));
  328. }
  329. }
  330. }
  331. }
  332. else
  333. if($data->action === "typing-started") {
  334. foreach ($this->clients as $client) {
  335. if($from !== $client){
  336. $client->send(json_encode(array('ip' => $from->remoteAddress, 'message' => ' is typing...', 'type' => 'typingOn', 'times' => round(microtime(true) * 1000))));
  337. }
  338. }
  339. }
  340. else
  341. if($data->action === "typing-ended") {
  342. foreach ($this->clients as $client) {
  343. if($from !== $client){
  344. $client->send(json_encode(array('ip' => $from->remoteAddress, 'message' => ' stoped typing...', 'type' => 'typingOff', 'times' => round(microtime(true) * 1000))));
  345. }
  346. }
  347. }
  348. else
  349. if($data->action === "sending") {
  350. $thread = $this->parseEmojiToStr($data->msg);
  351.  
  352. foreach ($this->clients as $client) {
  353. $client->send(json_encode(array('ip' => $from->remoteAddress, 'message' => $this->parseEmojiToImage($thread), 'type' => 'user', 'times' => round(microtime(true) * 1000))));
  354. }
  355. // here you must save messages to the database
  356. my_log("Saving message to database: $thread");
  357.  
  358. $this->insertData($from->remoteAddress, $thread, '', round(microtime(true) * 1000));
  359. }
  360.  
  361. }
  362.  
  363.  
  364.  
  365. public function onClose(ConnectionInterface $conn) {
  366. // The connection is closed, remove it, as we can no longer send it messages
  367. $this->clients->detach($conn);
  368.  
  369. //send to others clients message about disconnected user
  370. foreach ($this->clients as $client) {
  371. $client->send(json_encode(array('ip' => $conn->remoteAddress, 'message' => 'offline', 'type' => 'userLeft', 'times' => round(microtime(true) * 1000))));
  372. }
  373.  
  374. my_log("Connection {$conn->remoteAddress} has disconnected");
  375. }
  376.  
  377.  
  378.  
  379. public function onError(ConnectionInterface $conn, \Exception $e) {
  380. my_log("An error has occurred: {$e->getMessage()}");
  381. $conn->close();
  382. }
  383.  
  384.  
  385.  
  386.  
  387. /* CUSTOM FUNCTIONS */
  388. public function parseMessage($msg) {
  389. return json_decode($msg);
  390. }
  391.  
  392. public function parseEmojiToStr($str) {
  393. return $this->emojioneClient->toShort($str);
  394. }
  395.  
  396. public function parseEmojiToImage($str) {
  397. return $this->emojioneClient->shortnameToImage($str);
  398. }
  399.  
  400. public function connect() {
  401. $hostname = 'localhost';
  402. $dbname = 'cryptoIM';
  403. $username = 'root';
  404. $password = '';
  405.  
  406. try {
  407. $this->dbh = new PDO("mysql:host=$hostname; dbname=$dbname", $username, $password);
  408. $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  409. }
  410. catch(PDOException $e) {
  411. echo('ERROR: ' . $e->getMessage());
  412. }
  413. }
  414.  
  415. public function insertData($username, $messagetxt, $attachmentURI, $unixtime) {
  416. $query = $this->dbh->prepare("INSERT INTO inbox(users, message, attachmentURI, timestamps) VALUES (:username, :messagetxt, :attachmentURI, :unixtime)");
  417. $query->execute(array(
  418. ":username" => $username,
  419. ":messagetxt" => $messagetxt,
  420. ":attachmentURI" => $attachmentURI,
  421. ":unixtime" => $unixtime
  422. ));
  423. }
  424.  
  425. public function fetchMessages($index = NULL) {
  426. $message_list = array();
  427. $query = '';
  428. // Fetching only last 10 messages
  429.  
  430. if($index != NULL) {
  431. $query = $this->dbh->prepare("SELECT * FROM (SELECT * FROM inbox ORDER BY id DESC LIMIT $index, 10) tmp ORDER BY id ASC");
  432. $query->execute();
  433. }
  434. else {
  435. $query = $this->dbh->prepare("SELECT * FROM (SELECT * FROM inbox ORDER BY id DESC LIMIT 10) tmp ORDER BY id ASC");
  436. $query->execute();
  437. }
  438.  
  439. while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
  440. $message_list[] = array('id' => $row['id'], 'ip' => $row['users'], 'message' => $row['message'], 'type' => 'user', 'times' => $row['timestamps']);
  441. }
  442.  
  443. return json_encode($message_list);
  444. }
  445. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement