sse_client_example.html 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>自动评价SSE通知示例</title>
  7. <style>
  8. body {
  9. font-family: 'Arial', sans-serif;
  10. max-width: 800px;
  11. margin: 0 auto;
  12. padding: 20px;
  13. background-color: #f5f5f5;
  14. }
  15. .container {
  16. background-color: white;
  17. border-radius: 8px;
  18. box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  19. padding: 20px;
  20. }
  21. h1 {
  22. color: #333;
  23. text-align: center;
  24. }
  25. .status {
  26. margin: 20px 0;
  27. padding: 10px;
  28. border-radius: 4px;
  29. font-weight: bold;
  30. }
  31. .connected {
  32. background-color: #e8f5e8;
  33. color: #2e7d2e;
  34. border: 1px solid #a5d6a7;
  35. }
  36. .disconnected {
  37. background-color: #ffebee;
  38. color: #c62828;
  39. border: 1px solid #ef9a9a;
  40. }
  41. .updates {
  42. margin-top: 20px;
  43. }
  44. .update-item {
  45. margin-bottom: 15px;
  46. padding: 15px;
  47. border-radius: 4px;
  48. border-left: 4px solid #2196f3;
  49. background-color: #e3f2fd;
  50. }
  51. .update-item .timestamp {
  52. font-size: 0.9em;
  53. color: #555;
  54. margin-bottom: 8px;
  55. }
  56. .update-item .content {
  57. font-weight: bold;
  58. color: #333;
  59. }
  60. .score-update {
  61. border-left-color: #4caf50;
  62. background-color: #e8f5e8;
  63. }
  64. .notification {
  65. border-left-color: #ff9800;
  66. background-color: #fff8e1;
  67. }
  68. button {
  69. background-color: #2196f3;
  70. color: white;
  71. border: none;
  72. padding: 10px 15px;
  73. border-radius: 4px;
  74. cursor: pointer;
  75. margin-right: 10px;
  76. }
  77. button:hover {
  78. background-color: #0d8aee;
  79. }
  80. button:disabled {
  81. background-color: #cccccc;
  82. cursor: not-allowed;
  83. }
  84. .controls {
  85. margin-bottom: 20px;
  86. text-align: center;
  87. }
  88. </style>
  89. </head>
  90. <body>
  91. <div class="container">
  92. <h1>自动评价SSE通知</h1>
  93. <div class="controls">
  94. <button id="connectBtn">连接SSE</button>
  95. <button id="disconnectBtn" disabled>断开连接</button>
  96. </div>
  97. <div id="status" class="status disconnected">未连接</div>
  98. <div class="updates">
  99. <h2>评价更新记录</h2>
  100. <div id="updatesList">
  101. <p style="color: #666;">暂无更新记录</p>
  102. </div>
  103. </div>
  104. </div>
  105. <script>
  106. let eventSource = null;
  107. let clientID = 'web_client_' + Math.floor(Math.random() * 10000);
  108. const connectBtn = document.getElementById('connectBtn');
  109. const disconnectBtn = document.getElementById('disconnectBtn');
  110. const statusDiv = document.getElementById('status');
  111. const updatesList = document.getElementById('updatesList');
  112. // 连接SSE
  113. function connectSSE() {
  114. eventSource = new EventSource(`/sse/register`);
  115. eventSource.onopen = function(event) {
  116. updateStatus('已连接', 'connected');
  117. connectBtn.disabled = true;
  118. disconnectBtn.disabled = false;
  119. console.log('SSE连接已建立');
  120. };
  121. eventSource.onerror = function(event) {
  122. updateStatus('连接错误', 'disconnected');
  123. connectBtn.disabled = false;
  124. disconnectBtn.disabled = true;
  125. console.error('SSE连接错误:', event);
  126. };
  127. eventSource.addEventListener('connected', function(event) {
  128. const data = JSON.parse(event.data);
  129. addUpdateItem('系统通知', `SSE连接已建立 (ID: ${data.clientID})`, 'notification');
  130. });
  131. eventSource.addEventListener('ping', function(event) {
  132. const data = JSON.parse(event.data);
  133. console.log('心跳:', data);
  134. });
  135. eventSource.addEventListener('evaluation_update', function(event) {
  136. const data = JSON.parse(event.data);
  137. handleEvaluationUpdate(data);
  138. });
  139. }
  140. // 断开SSE连接
  141. function disconnectSSE() {
  142. if (eventSource) {
  143. eventSource.close();
  144. eventSource = null;
  145. updateStatus('已断开', 'disconnected');
  146. connectBtn.disabled = false;
  147. disconnectBtn.disabled = true;
  148. console.log('SSE连接已断开');
  149. }
  150. }
  151. // 更新连接状态
  152. function updateStatus(text, className) {
  153. statusDiv.textContent = text;
  154. statusDiv.className = 'status ' + className;
  155. }
  156. // 处理评价更新
  157. function handleEvaluationUpdate(data) {
  158. if (data.type === 'evaluation_update') {
  159. const message = `
  160. <strong>评价项目:</strong> ${data.evaName}<br>
  161. <strong>序号:</strong> ${data.seqNo}<br>
  162. <strong>操作得分:</strong> ${data.operScore}<br>
  163. <strong>课程总分:</strong> ${data.courseScore}<br>
  164. <strong>更新时间:</strong> ${data.timestamp}
  165. `;
  166. addUpdateItem('评价得分更新', message, 'score-update');
  167. }
  168. }
  169. // 添加更新记录
  170. function addUpdateItem(title, content, className) {
  171. const item = document.createElement('div');
  172. item.className = `update-item ${className}`;
  173. const timestamp = new Date().toLocaleString();
  174. item.innerHTML = `
  175. <div class="timestamp">${timestamp}</div>
  176. <div class="content">
  177. <strong>${title}</strong><br>
  178. ${content}
  179. </div>
  180. `;
  181. // 如果是第一条记录,清空"暂无更新记录"的提示
  182. if (updatesList.children.length === 1 && updatesList.children[0].textContent.includes('暂无更新记录')) {
  183. updatesList.innerHTML = '';
  184. }
  185. // 将新记录插入到顶部
  186. updatesList.insertBefore(item, updatesList.firstChild);
  187. // 限制显示的记录数量
  188. while (updatesList.children.length > 10) {
  189. updatesList.removeChild(updatesList.lastChild);
  190. }
  191. }
  192. // 绑定按钮事件
  193. connectBtn.addEventListener('click', connectSSE);
  194. disconnectBtn.addEventListener('click', disconnectSSE);
  195. </script>
  196. </body>
  197. </html>