index.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <html><head>
  2. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  3. <title>workerman-chat PHP聊天室 Websocket(HTLM5/Flash)+PHP多进程socket实时推送技术</title>
  4. <link href="/css/bootstrap.min.css" rel="stylesheet">
  5. <link href="/css/jquery-sinaEmotion-2.1.0.min.css" rel="stylesheet">
  6. <link href="/css/style.css" rel="stylesheet">
  7. <script type="text/javascript" src="/js/swfobject.js"></script>
  8. <script type="text/javascript" src="/js/web_socket.js"></script>
  9. <script type="text/javascript" src="/js/jquery.min.js"></script>
  10. <script type="text/javascript" src="/js/jquery-sinaEmotion-2.1.0.min.js"></script>
  11. <script type="text/javascript">
  12. if (typeof console == "undefined") { this.console = { log: function (msg) { } };}
  13. // 如果浏览器不支持websocket,会使用这个flash自动模拟websocket协议,此过程对开发者透明
  14. WEB_SOCKET_SWF_LOCATION = "/swf/WebSocketMain.swf";
  15. // 开启flash的websocket debug
  16. WEB_SOCKET_DEBUG = true;
  17. var ws, name, client_list={};
  18. // 连接服务端
  19. function connect() {
  20. // 创建websocket
  21. ws = new WebSocket("ws://127.0.0.1:7272");
  22. // 当socket连接打开时,输入用户名
  23. ws.onopen = onopen;
  24. // 当有消息时根据消息类型显示不同信息
  25. ws.onmessage = onmessage;
  26. ws.onclose = function() {
  27. console.log("连接关闭,定时重连");
  28. connect();
  29. };
  30. ws.onerror = function() {
  31. console.log("出现错误");
  32. };
  33. }
  34. // 连接建立时发送登录信息
  35. function onopen()
  36. {
  37. if(!name)
  38. {
  39. show_prompt();
  40. }
  41. // 登录
  42. var login_data = '{"type":"login","client_name":"'+name.replace(/"/g, '\\"')+'","room_id":"<?php echo isset($_GET['room_id']) ? $_GET['room_id'] : 1?>"}';
  43. console.log("websocket握手成功,发送登录数据:"+login_data);
  44. ws.send(login_data);
  45. }
  46. // 服务端发来消息时
  47. function onmessage(e)
  48. {
  49. console.log(e.data);
  50. var data = JSON.parse(e.data);
  51. switch(data['type']){
  52. // 服务端ping客户端
  53. case 'ping':
  54. ws.send('{"type":"pong"}');
  55. break;;
  56. // 登录 更新用户列表
  57. case 'login':
  58. //{"type":"login","client_id":xxx,"client_name":"xxx","client_list":"[...]","time":"xxx"}
  59. say(data['client_id'], data['client_name'], data['client_name']+' 加入了聊天室', data['time']);
  60. if(data['client_list'])
  61. {
  62. client_list = data['client_list'];
  63. }
  64. else
  65. {
  66. client_list[data['client_id']] = data['client_name'];
  67. }
  68. flush_client_list();
  69. console.log(data['client_name']+"登录成功");
  70. break;
  71. // 发言
  72. case 'say':
  73. //{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"}
  74. say(data['from_client_id'], data['from_client_name'], data['content'], data['time']);
  75. break;
  76. // 用户退出 更新用户列表
  77. case 'logout':
  78. //{"type":"logout","client_id":xxx,"time":"xxx"}
  79. say(data['from_client_id'], data['from_client_name'], data['from_client_name']+' 退出了', data['time']);
  80. delete client_list[data['from_client_id']];
  81. flush_client_list();
  82. }
  83. }
  84. // 输入姓名
  85. function show_prompt(){
  86. name = prompt('输入你的名字:', '');
  87. if(!name || name=='null'){
  88. name = '游客';
  89. }
  90. }
  91. // 提交对话
  92. function onSubmit() {
  93. var input = document.getElementById("textarea");
  94. var to_client_id = $("#client_list option:selected").attr("value");
  95. var to_client_name = $("#client_list option:selected").text();
  96. ws.send('{"type":"say","to_client_id":"'+to_client_id+'","to_client_name":"'+to_client_name+'","content":"'+input.value.replace(/"/g, '\\"').replace(/\n/g,'\\n').replace(/\r/g, '\\r')+'"}');
  97. input.value = "";
  98. input.focus();
  99. }
  100. // 刷新用户列表框
  101. function flush_client_list(){
  102. var userlist_window = $("#userlist");
  103. var client_list_slelect = $("#client_list");
  104. userlist_window.empty();
  105. client_list_slelect.empty();
  106. userlist_window.append('<h4>在线用户</h4><ul>');
  107. client_list_slelect.append('<option value="all" id="cli_all">所有人</option>');
  108. for(var p in client_list){
  109. userlist_window.append('<li id="'+p+'">'+client_list[p]+'</li>');
  110. client_list_slelect.append('<option value="'+p+'">'+client_list[p]+'</option>');
  111. }
  112. $("#client_list").val(select_client_id);
  113. userlist_window.append('</ul>');
  114. }
  115. // 发言
  116. function say(from_client_id, from_client_name, content, time){
  117. //解析新浪微博图片
  118. content = content.replace(/(http|https):\/\/[\w]+.sinaimg.cn[\S]+(jpg|png|gif)/gi, function(img){
  119. return "<a target='_blank' href='"+img+"'>"+"<img src='"+img+"'>"+"</a>";}
  120. );
  121. //解析url
  122. content = content.replace(/(http|https):\/\/[\S]+/gi, function(url){
  123. if(url.indexOf(".sinaimg.cn/") < 0)
  124. return "<a target='_blank' href='"+url+"'>"+url+"</a>";
  125. else
  126. return url;
  127. }
  128. );
  129. $("#dialog").append('<div class="speech_item"><img src="http://lorempixel.com/38/38/?'+from_client_id+'" class="user_icon" /> '+from_client_name+' <br> '+time+'<div style="clear:both;"></div><p class="triangle-isosceles top">'+content+'</p> </div>').parseEmotion();
  130. }
  131. $(function(){
  132. select_client_id = 'all';
  133. $("#client_list").change(function(){
  134. select_client_id = $("#client_list option:selected").attr("value");
  135. });
  136. $('.face').click(function(event){
  137. $(this).sinaEmotion();
  138. event.stopPropagation();
  139. });
  140. });
  141. </script>
  142. </head>
  143. <body onload="connect();">
  144. <div class="container">
  145. <div class="row clearfix">
  146. <div class="col-md-1 column">
  147. </div>
  148. <div class="col-md-6 column">
  149. <div class="thumbnail">
  150. <div class="caption" id="dialog"></div>
  151. </div>
  152. <form onsubmit="onSubmit(); return false;">
  153. <select style="margin-bottom:8px" id="client_list">
  154. <option value="all">所有人</option>
  155. </select>
  156. <textarea class="textarea thumbnail" id="textarea"></textarea>
  157. <div class="say-btn">
  158. <input type="button" class="btn btn-default face pull-left" value="表情" />
  159. <input type="submit" class="btn btn-default" value="发表" />
  160. </div>
  161. </form>
  162. <div>
  163. &nbsp;&nbsp;&nbsp;&nbsp;<b>房间列表:</b>(当前在&nbsp;房间<?php echo isset($_GET['room_id'])&&intval($_GET['room_id'])>0 ? intval($_GET['room_id']):1; ?>)<br>
  164. &nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=1">房间1</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=2">房间2</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=3">房间3</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=4">房间4</a>
  165. <br><br>
  166. </div>
  167. <p class="cp">PHP多进程+Websocket(HTML5/Flash)+PHP Socket实时推送技术&nbsp;&nbsp;&nbsp;&nbsp;Powered by <a href="http://www.workerman.net/workerman-chat" target="_blank">workerman-chat</a></p>
  168. </div>
  169. <div class="col-md-3 column">
  170. <div class="thumbnail">
  171. <div class="caption" id="userlist"></div>
  172. </div>
  173. <a href="http://workerman.net:8383" target="_blank"><img style="width:252px;margin-left:5px;" src="/img/workerman-todpole.png"></a>
  174. </div>
  175. </div>
  176. </div>
  177. <script type="text/javascript">var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F7b1919221e89d2aa5711e4deb935debd' type='text/javascript'%3E%3C/script%3E"));</script>
  178. <script type="text/javascript">
  179. // 动态自适应屏幕
  180. document.write('<meta name="viewport" content="width=device-width,initial-scale=1">');
  181. $("textarea").on("keydown", function(e) {
  182. // 按enter键自动提交
  183. if(e.keyCode === 13 && !e.ctrlKey) {
  184. e.preventDefault();
  185. $('form').submit();
  186. return false;
  187. }
  188. // 按ctrl+enter组合键换行
  189. if(e.keyCode === 13 && e.ctrlKey) {
  190. $(this).val(function(i,val){
  191. return val + "\n";
  192. });
  193. }
  194. });
  195. </script>
  196. </body>
  197. </html>