chatServices.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. angular.module('chatServices', [])
  2. .factory('Connection', function($rootScope, $timeout, $interval, $location) {
  3. var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket;
  4. var chatSocket = null;
  5. var ping = null;
  6. var service = {
  7. username: '',
  8. error: null,
  9. messages: [],
  10. status: 'disconnected',
  11. hasRoom: function() {
  12. return $location.path() != '';
  13. },
  14. isConnected: function() {
  15. return this.status == 'connected';
  16. },
  17. addListener: function(f) {
  18. messageListeners.add(f);
  19. }
  20. };
  21. function wrap(func) {
  22. return function() {
  23. var args = arguments;
  24. $timeout(function() {
  25. func.apply(null, args);
  26. });
  27. }
  28. };
  29. function makeid() {
  30. var text = "";
  31. var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  32. for( var i=0; i < 5; i++ )
  33. text += possible.charAt(Math.floor(Math.random() * possible.length));
  34. return text;
  35. }
  36. function getRoom() {
  37. if(!$location.path()) {
  38. $location.path(makeid());
  39. }
  40. return $location.path();
  41. }
  42. service.connect = function(username) {
  43. if(service.status != 'disconnected') return;
  44. service.error = null;
  45. service.status = 'connecting';
  46. var url = jsRoutes.controllers.Application.chat(username, getRoom()).webSocketURL();
  47. if(window.location.protocol == 'https:') {
  48. url = url.replace('ws:', 'wss:');
  49. }
  50. chatSocket = new WS(url);
  51. chatSocket.onmessage = wrap(function(event) {
  52. var message = JSON.parse(event.data);
  53. if(message.error) {
  54. service.error = message.error;
  55. }
  56. if(message.kind != "pong") {
  57. $rootScope.$broadcast('ws:message', message);
  58. }
  59. });
  60. chatSocket.onopen = wrap(function() {
  61. $rootScope.$broadcast('ws:connected', username);
  62. service.status = 'connected';
  63. service.username = username;
  64. ping = $interval(function() {
  65. service.send('/ping');
  66. }, 60000, 0, false);
  67. });
  68. chatSocket.onclose = wrap(function() {
  69. $rootScope.$broadcast('ws:disconnected');
  70. service.status = 'disconnected';
  71. service.username = '';
  72. $interval.cancel(ping);
  73. });
  74. }
  75. service.disconnect = function() {
  76. chatSocket.close();
  77. chatSocket = null;
  78. }
  79. service.send = function(message) {
  80. chatSocket.send(JSON.stringify({text: message}));
  81. }
  82. return service;
  83. })
  84. .factory('Chat', function($rootScope, Connection) {
  85. var service = {
  86. username: '',
  87. messages: [],
  88. receive: function(message) {
  89. if(arguments.length == 3) {
  90. message = {
  91. kind: arguments[0],
  92. user: arguments[1],
  93. message: arguments[2]
  94. };
  95. }
  96. service.messages.push(message);
  97. $rootScope.$broadcast('chat:message', message);
  98. },
  99. send: Connection.send
  100. };
  101. $rootScope.$on('ws:connected', function(event, username) {
  102. service.username = username;
  103. });
  104. $rootScope.$on('ws:message', function(event, message) {
  105. if(message.kind == "talk") {
  106. service.receive(message);
  107. }
  108. else if(message.kind == "join") {
  109. service.receive("join", message.user, " has joined.");
  110. }
  111. else if(message.kind == "quit") {
  112. service.receive("quit", message.user, " has left.");
  113. }
  114. });
  115. $rootScope.$on('ws:disconnected', function() {
  116. service.messages = [];
  117. service.username = '';
  118. });
  119. if(Connection.isConnected()) {
  120. service.username = Connection.username;
  121. }
  122. return service;
  123. })