springBoot

浅谈WebSocket WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就可以建立一条快速通道,两者就可以实现数据互传了。说白了,就是打破了传统的http协议的无状态传输(只能浏览器请求,服务端响应),websocket全双工通讯,就是浏览器和服务器进行一次握手,浏览器可以随时给服务器发送信息,服务器也可以随时主动发送信息给浏览器了。对webSocket原理有兴趣的客官,可以自行百度。 2.环境搭建 因为是根据项目的需求来的,所以这里我只介绍在SpringBoot下使用WebSocket的其中一种实现【STOMP协议】。因此整个工程涉及websocket使用的大致框架为SpringBoot+Maven+websocket,其他框架的基础搭建,我这里就不说了,相信各位也都很熟悉,我就直接集成websocket了。 在pox.xml加上对springBoot对WebSocket的支持: <!– webSocket –>
<dependency>

&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;<br/>
&lt;artifactId&gt;spring-boot-starter-websocket&lt;/artifactId&gt;<br/>

&lt;/dependency&gt;
这样SpringBoot就和WebSocket集成好了,我们就可以直接使用SpringBoot提供对WebSocket操作的API了 3.编码实现 ①在Spring上下文中添加对WebSocket的配置 import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; /**

  • 配置WebSocket
    /
    @Configuration
    //注解开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
    @Override
    //注册STOMP协议的节点(endpoint),并映射指定的url
    public void registerStompEndpoints(StompEndpointRegistry registry) {
    //注册一个STOMP的endpoint,并指定使用SockJS协议
    registry.addEndpoint(“/endpointOyzc”).setAllowedOrigins(“
    ”).withSockJS();
    }
    @Override
    //配置消息代理(Message Broker)
    public void configureMessageBroker(MessageBrokerRegistry registry) {
    //点对点应配置一个/user消息代理,广播式应配置一个/topic消息代理
    registry.enableSimpleBroker(“/topic”,“/user”);
    //点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/
    registry.setUserDestinationPrefix(“/user”);
    }
    }
    介绍以上几个相关的注解和方法: 1.@EnableWebSocketMessageBroker:开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样。 2.AbstractWebSocketMessageBrokerConfigurer:继承WebSocket消息代理的类,配置相关信息。 3.registry.addEndpoint(“/endpointOyzc”).setAllowedOrigins(“*”).withSockJS(); 添加一个访问端点“/endpointGym”,客户端打开双通道时需要的url,允许所有的域名跨域访问,指定使用SockJS协议。 4. registry.enableSimpleBroker(“/topic”,“/user”); 配置一个/topic广播消息代理和“/user”一对一消息代理
  1. registry.setUserDestinationPrefix(“/user”);点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/   ②实现服务器主动向客户端推送消息 SpringBoot封装得太好,webSocket用起来太简单(好处:用起来方便,坏处:你不知道底层实现) 1.一对多的实现: 先上后台java的代码 package com.cheng.sbjm.boot; import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.messaging.simp.SimpMessagingTemplate;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Controller;
    import com.cheng.sbjm.domain.User; @Controller
    public class WebSocketController { @Autowired
    private SimpMessagingTemplate template; //广播推送消息
    @Scheduled(fixedRate = 10000)
    public void sendTopicMessage() {
    System.out.println(“后台广播推送!”);
    User user=new User();
    user.setUserName(“oyzc”);
    user.setAge(10);
    this.template.convertAndSend(“/topic/getResponse”,user);
    }
    }
    简单介绍一下 1.SimpMessagingTemplate:SpringBoot提供操作WebSocket的对象 2.@Scheduled(fixedRate = 10000):为了测试,定时10S执行这个方法,向客户端推送 3.template.convertAndSend(“/topic/getResponse”,new AricResponse(“后台实时推送:,Oyzc!”)); :直接向前端推送消息。 3.1参数一:客户端监听指定通道时,设定的访问服务器的URL 3.2参数二:发送的消息(可以是对象、字符串等等)   在上客户端的代码(PC现代浏览器) html页面: &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;websocket.html&lt;/title&gt;
    &lt;meta name=“keywords” content=“keyword1,keyword2,keyword3”&gt;
    &lt;meta name=“description” content=“this is my page”&gt;
    &lt;meta name=“content-type” content=“text/html” charset=“UTF-8”&gt;
    &lt;!–&lt;link rel=“stylesheet” type=“text/css” href=“./styles.css”&gt;–&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;div&gt;
    &lt;p id=“response”&gt;&lt;/p&gt;
    &lt;/div&gt; &lt;!– 独立JS –&gt;
    &lt;script type=“text/javascript” src=“jquery.min.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;script type=“text/javascript” src=“webSocket.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;script type=“text/javascript” src=“sockjs.min.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;script type=“text/javascript” src=“stomp.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;/body&gt;
    &lt;/html&gt;
    JS代码[webSocket.js] var stompClient = null;
    //加载完浏览器后 调用connect(),打开双通道
    \((function(){<br/> //打开双通道<br/> connect()<br/> })<br/> //强制关闭浏览器 调用websocket.close(),进行正常关闭<br/> window.onunload = function() {<br/> disconnect()<br/> }<br/> function connect(){<br/> var socket = new SockJS(&#39;http://127.0.0.1:9091/sbjm-cheng/endpointOyzc&#39;); //连接SockJS的endpoint名称为&#34;endpointOyzc&#34;<br/> stompClient = Stomp.over(socket);//使用STMOP子协议的WebSocket客户端<br/> stompClient.connect({},function(frame){//连接WebSocket服务端<br/> console.log(&#39;Connected:&#39; + frame);<br/> //通过stompClient.subscribe订阅/topic/getResponse 目标(destination)发送的消息<br/> stompClient.subscribe(&#39;/topic/getResponse&#39;,function(response){<br/> showResponse(JSON.parse(response.body));<br/> });<br/> });<br/> } //关闭双通道<br/> function disconnect(){<br/> if(stompClient != null) {<br/> stompClient.disconnect();<br/> }<br/> console.log(&#34;Disconnected&#34;);<br/> }<br/> function showResponse(message){<br/> var response = \)(“#response”);
    response.append(“&lt;p&gt;”+message.userName+“&lt;/p&gt;”);
    }
    值得注意的是,只需要在连接服务器注册端点endPoint时,写访问服务器的全路径URL: new SockJS(‘http://127.0.0.1:9091/sbjm-cheng/endpointOyzc&#39;); 其他监听指定服务器广播的URL不需要写全路径  stompClient.subscribe(’/topic/getResponse‘,function(response){
                    showResponse(JSON.parse(response.body));             }); 2.一对一的实现 先上后台java的代码 package com.cheng.sbjm.boot; import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.messaging.simp.SimpMessagingTemplate;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Controller;
    import com.cheng.sbjm.domain.User; @Controller
    public class WebSocketController { @Autowired
    private SimpMessagingTemplate template; //一对一推送消息
    @Scheduled(fixedRate = 10000)
    public void sendQueueMessage() {
    System.out.println(“后台一对一推送!”);
    User user=new User();
    user.setUserId(1);
    user.setUserName(“oyzc”);
    user.setAge(10);
    this.template.convertAndSendToUser(user.getUserId()+“”,“/queue/getResponse”,user);
    }
    }
    简单介绍一下: 1.SimpMessagingTemplate:SpringBoot提供操作WebSocket的对象 2.@Scheduled(fixedRate = 10000):为了测试,定时10S执行这个方法,向客户端推送 3.template.convertAndSendToUser(user.getUserId()+“”,“/queue/getResponse”,user); :直接向前端推送消息。 3.1参数一:指定客户端接收的用户标识(一般用用户ID) 3.2参数二:客户端监听指定通道时,设定的访问服务器的URL(客户端访问URL跟广播有些许不同) 3.3参数三:向目标发送消息体(实体、字符串等等)   在上客户端的代码(PC现代浏览器) html页面: &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;websocket.html&lt;/title&gt; &lt;meta name=“keywords” content=“keyword1,keyword2,keyword3”&gt;
    &lt;meta name=“description” content=“this is my page”&gt;
    &lt;meta name=“content-type” content=“text/html” charset=“UTF-8”&gt;
    &lt;!–&lt;link rel=“stylesheet” type=“text/css” href=“./styles.css”&gt;–&gt;
    &lt;!– 独立css –&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;div&gt;
    &lt;p id=“response”&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;!– 独立JS –&gt;
    &lt;script type=“text/javascript” src=“jquery.min.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;script type=“text/javascript” src=“webSocket.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;script type=“text/javascript” src=“sockjs.min.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;script type=“text/javascript” src=“stomp.js” charset=“utf-8”&gt;&lt;/script&gt;
    &lt;/body&gt;
    &lt;/html&gt;
    JS代码[webSocket.js] var stompClient = null;
    //加载完浏览器后 调用connect(),打开双通道
    \((function(){<br/> //打开双通道<br/> connect()<br/> })<br/> //强制关闭浏览器 调用websocket.close(),进行正常关闭<br/> window.onunload = function() {<br/> disconnect()<br/> }<br/> function connect(){<br/> var userId=1;<br/> var socket = new SockJS(&#39;http://127.0.0.1:9091/sbjm-cheng/endpointOyzc&#39;); //连接SockJS的endpoint名称为&#34;endpointOyzc&#34;<br/> stompClient = Stomp.over(socket);//使用STMOP子协议的WebSocket客户端<br/> stompClient.connect({},function(frame){//连接WebSocket服务端<br/> console.log(&#39;Connected:&#39; + frame);<br/> //通过stompClient.subscribe订阅/topic/getResponse 目标(destination)发送的消息<br/> stompClient.subscribe(&#39;/user/&#39; + userId + &#39;/queue/getResponse&#39;,function(response){<br/> var code=JSON.parse(response.body);<br/> showResponse(code)<br/> });<br/> });<br/> }<br/> //关闭双通道<br/> function disconnect(){<br/> if(stompClient != null) {<br/> stompClient.disconnect();<br/> }<br/> console.log(&#34;Disconnected&#34;);<br/> }<br/> function showResponse(message){<br/> var response = \)(“#response”);
    response.append(“&lt;p&gt;只有userID为”+message.userId+“的人才能收到&lt;/p&gt;”);
    }
    与广播不同的是,在指定通道的URL加个用户标识:  stompClient.subscribe(’/user/‘ + userId + ’/queue/getResponse‘,function(response){
                var code=JSON.parse(response.body);                      
                showResponse(code)                           }); 该标识userId必须与服务器推送消息时设置的用户标识一致   以上就是实现服务器实时向客户端推送消息,各位可以按照各自的需求进行配合使用。   ③实现客户端与服务器之间的直接交互,聊天室demo[在②的基础上添加了一些代码] 1.在webSocket配置中,增加2个WebSocket的代理 package com.cheng.sbjm.configure; import org.springframework.context.annotation.Configuration;
    import org.springframework.messaging.simp.config.MessageBrokerRegistry;
    import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
    import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
    import org.springframework.web.socket.config.annotation.StompEndpointRegistry; /**
    • 配置WebSocket
      /
      @Configuration
      //注解开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样
      @EnableWebSocketMessageBroker
      public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{ @Override
      //注册STOMP协议的节点(endpoint),并映射指定的url
      public void registerStompEndpoints(StompEndpointRegistry registry) {
      //注册一个STOMP的endpoint,并指定使用SockJS协议
      registry.addEndpoint(“/endpointOyzc”).setAllowedOrigins(“
      ”).withSockJS();
      } @Override
      //配置消息代理(Message Broker)
      public void configureMessageBroker(MessageBrokerRegistry registry) {
      //点对点应配置一个/user消息代理,广播式应配置一个/topic消息代理,群发(mass),单独聊天(alone)
      registry.enableSimpleBroker(“/topic”,“/user”,“/mass”,“/alone”);
      //点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/
      registry.setUserDestinationPrefix(“/user”); } }
      “/mass”用以代理群发消息 “/alone”用以代码一对一聊天 2.java后台实现 package com.cheng.sbjm.boot; import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.messaging.handler.annotation.MessageMapping;
      import org.springframework.messaging.handler.annotation.SendTo;
      import org.springframework.messaging.simp.SimpMessagingTemplate;
      import org.springframework.stereotype.Controller;
      import com.cheng.sbjm.onput.ChatRoomRequest;
      import com.cheng.sbjm.onput.ChatRoomResponse; @Controller
      public class WebSocketController { @Autowired
      private SimpMessagingTemplate template;
      //客户端主动发送消息到服务端,服务端马上回应指定的客户端消息
      //类似http无状态请求,但是有质的区别
      //websocket可以从服务器指定发送哪个客户端,而不像http只能响应请求端 //群发
      @MessageMapping(“/massRequest”)
      //SendTo 发送至 Broker 下的指定订阅路径
      @SendTo(“/mass/getResponse”)
      public ChatRoomResponse mass(ChatRoomRequest chatRoomRequest){
      //方法用于群发测试
      System.out.println(“name = ” + chatRoomRequest.getName());
      System.out.println(“chatValue = ” + chatRoomRequest.getChatValue());
      ChatRoomResponse response=new ChatRoomResponse();
      response.setName(chatRoomRequest.getName());
      response.setChatValue(chatRoomRequest.getChatValue());
      return response;
      } //单独聊天
      @MessageMapping(“/aloneRequest”)
      public ChatRoomResponse alone(ChatRoomRequest chatRoomRequest){
      //方法用于一对一测试
      System.out.println(“userId = ” + chatRoomRequest.getUserId());
      System.out.println(“name = ” + chatRoomRequest.getName());
      System.out.println(“chatValue = ” + chatRoomRequest.getChatValue());
      ChatRoomResponse response=new ChatRoomResponse();
      response.setName(chatRoomRequest.getName());
      response.setChatValue(chatRoomRequest.getChatValue());
      this.template.convertAndSendToUser(chatRoomRequest.getUserId()+“”,“/alone/getResponse”,response);
      return response;
      }
      }
      简单介绍新的注解一下: 一.@MessageMapping(“/massRequest”):类似与@RequestMapping,客户端请求服务器的URL,前提是双方端点已经打开 二.@SendTo(“/mass/getResponse”):作用跟convertAndSend类似,广播发给与该通道相连的客户端 其他已经在前面解释过了。 3.html代码 &lt;!DOCTYPE html&gt;
      &lt;html&gt;
      &lt;head&gt;
      &lt;title&gt;login.html&lt;/title&gt; &lt;meta name=“keywords” content=“keyword1,keyword2,keyword3”&gt;
      &lt;meta name=“description” content=“this is my page”&gt;
      &lt;meta name=“content-type” content=“text/html” charset=“UTF-8”&gt;
      &lt;!–&lt;link rel=“stylesheet” type=“text/css” href=“./styles.css”&gt;–&gt;
      &lt;!– 独立css –&gt;
      &lt;link rel=“stylesheet” type=“text/css” href=“chatroom.css”&gt;
      &lt;/head&gt; &lt;body&gt;
      &lt;div&gt;
      &lt;div style=“float:left;width:40%”&gt;
      &lt;p&gt;请选择你是谁:&lt;/p&gt;
      &lt;select id=“selectName” onchange=“sendAloneUser();”&gt;
      &lt;option value=“1”&gt;请选择&lt;/option&gt;
      &lt;option value=“ALong”&gt;ALong&lt;/option&gt;
      &lt;option value=“AKan”&gt;AKan&lt;/option&gt;
      &lt;option value=“AYuan”&gt;AYuan&lt;/option&gt;
      &lt;option value=“ALai”&gt;ALai&lt;/option&gt;
      &lt;option value=“ASheng”&gt;ASheng&lt;/option&gt;
      &lt;/select&gt;
      &lt;div class=“chatWindow”&gt;
      &lt;p style=“color:darkgrey”&gt;群聊:&lt;/p&gt;
      &lt;section id=“chatRecord” class=“chatRecord”&gt;
      &lt;p id=“titleval” style=“color:#CD2626;”&gt;&lt;/p&gt;
      &lt;/section&gt;
      &lt;section class=“sendWindow”&gt;
      &lt;textarea name=“sendChatValue” id=“sendChatValue” class=“sendChatValue”&gt;&lt;/textarea&gt;
      &lt;input type=“button” name=“sendMessage” id=“sendMessage” class=“sendMessage” onclick=“sendMassMessage()” value=“发送”&gt;
      &lt;/section&gt;
      &lt;/div&gt;
      &lt;/div&gt; &lt;div style=“float:right; width:40%”&gt;
      &lt;p&gt;请选择你要发给谁:&lt;/p&gt;
      &lt;select id=“selectName2”&gt;
      &lt;option value=“1”&gt;请选择&lt;/option&gt;
      &lt;option value=“ALong”&gt;ALong&lt;/option&gt;
      &lt;option value=“AKan”&gt;AKan&lt;/option&gt;
      &lt;option value=“AYuan”&gt;AYuan&lt;/option&gt;
      &lt;option value=“ALai”&gt;ALai&lt;/option&gt;
      &lt;option value=“ASheng”&gt;ASheng&lt;/option&gt;
      &lt;/select&gt;
      &lt;div class=“chatWindow”&gt;
      &lt;p style=“color:darkgrey”&gt;单独聊:&lt;/p&gt;
      &lt;section id=“chatRecord2” class=“chatRecord”&gt;
      &lt;p id=“titleval” style=“color:#CD2626;”&gt;&lt;/p&gt;
      &lt;/section&gt;
      &lt;section class=“sendWindow”&gt;
      &lt;textarea name=“sendChatValue2” id=“sendChatValue2” class=“sendChatValue”&gt;&lt;/textarea&gt;
      &lt;input type=“button” name=“sendMessage” id=“sendMessage” class=“sendMessage” onclick=“sendAloneMessage()” value=“发送”&gt;
      &lt;/section&gt;
      &lt;/div&gt;
      &lt;/div&gt;
      &lt;/div&gt;
      &lt;!– 独立JS –&gt;
      &lt;script type=“text/javascript” src=“jquery.min.js” charset=“utf-8”&gt;&lt;/script&gt;
      &lt;script type=“text/javascript” src=“chatroom.js” charset=“utf-8”&gt;&lt;/script&gt;
      &lt;script type=“text/javascript” src=“sockjs.min.js” charset=“utf-8”&gt;&lt;/script&gt;
      &lt;script type=“text/javascript” src=“stomp.js” charset=“utf-8”&gt;&lt;/script&gt;
      &lt;/body&gt;
      &lt;/html&gt;
      JS代码[chatroom.js]: var stompClient = null; //加载完浏览器后 调用connect(),打开双通道
      \((function(){<br/> //打开双通道<br/> connect()<br/> }) //强制关闭浏览器 调用websocket.close(),进行正常关闭<br/> window.onunload = function() {<br/> disconnect()<br/> } //打开双通道<br/> function connect(){<br/> var socket = new SockJS(&#39;http://172.16.0.56:9091/sbjm-cheng/endpointOyzc&#39;); //连接SockJS的endpoint名称为&#34;endpointAric&#34;<br/> stompClient = Stomp.over(socket);//使用STMOP子协议的WebSocket客户端<br/> stompClient.connect({},function(frame){//连接WebSocket服务端 console.log(&#39;Connected:&#39; + frame);<br/> //广播接收信息<br/> stompTopic(); });<br/> } //关闭双通道<br/> function disconnect(){<br/> if(stompClient != null) {<br/> stompClient.disconnect();<br/> }<br/> console.log(&#34;Disconnected&#34;);<br/> } //广播(一对多)<br/> function stompTopic(){<br/> //通过stompClient.subscribe订阅/topic/getResponse 目标(destination)发送的消息(广播接收信息)<br/> stompClient.subscribe(&#39;/mass/getResponse&#39;,function(response){<br/> var message=JSON.parse(response.body);<br/> //展示广播的接收的内容接收<br/> var response = \)(“#chatRecord”);
      response.append(“&lt;p&gt;&lt;span&gt;”+message.name+“:&lt;/span&gt;&lt;span&gt;”+message.chatValue+“&lt;/span&gt;&lt;/p&gt;”);
      });
      } //列队(一对一)
      function stompQueue(){ var userId=\((&#34;#selectName&#34;).val();<br/> alert(&#34;监听:&#34;+userId)<br/> //通过stompClient.subscribe订阅/topic/getResponse 目标(destination)发送的消息(队列接收信息)<br/> stompClient.subscribe(&#39;/user/&#39; + userId + &#39;/alone/getResponse&#39;,function(response){<br/> var message=JSON.parse(response.body);<br/> //展示一对一的接收的内容接收<br/> var response = \)(“#chatRecord2”);
      response.append(“&lt;p&gt;&lt;span&gt;”+message.name+“:&lt;/span&gt;&lt;span&gt;”+message.chatValue+“&lt;/span&gt;&lt;/p&gt;”);
      });
      } //选择发送给谁的时候触发连接服务器
      function sendAloneUser(){
      stompQueue();
      } //群发
      function sendMassMessage(){
      var postValue={};
      var chatValue=\((&#34;#sendChatValue&#34;);<br/> var userName=\)(“#selectName”).val();
      postValue.name=userName;
      postValue.chatValue=chatValue.val();
      if(userName==1||userName==null){
      alert(“请选择你是谁!”);
      return;
      }
      if(chatValue==“”||userName==null){
      alert(“不能发送空消息!”);
      return;
      }
      stompClient.send(“/massRequest”,{},JSON.stringify(postValue));
      chatValue.val(“”);
      }
      //单独发
      function sendAloneMessage(){
      var postValue={};
      var chatValue=\((&#34;#sendChatValue2&#34;);<br/> var userName=\)(“#selectName”).val();
      var sendToId=\((&#34;#selectName2&#34;).val();<br/> var response = \)(“#chatRecord2”);
      postValue.name=userName;
      postValue.chatValue=chatValue.val();
      postValue.userId=sendToId;
      if(userName==1||userName==null){
      alert(“请选择你是谁!”);
      return;
      }
      if(sendToId==1||sendToId==null){
      alert(“请选择你要发给谁!”);
      return;
      }
      if(chatValue==“”||userName==null){
      alert(“不能发送空消息!”);
      return;
      }
      stompClient.send(“/aloneRequest”,{},JSON.stringify(postValue));
      response.append(“&lt;p&gt;&lt;span&gt;”+userName+“:&lt;/span&gt;&lt;span&gt;”+chatValue.val()+“&lt;/span&gt;&lt;/p&gt;”);
      chatValue.val(“”);
      }
      chatroom.css .chatWindow{ width: 100%;
      height: 500px;
      border: 1px solid blue;
      }
      .chatRecord{
      width: 100%;
      height: 400px;
      border-bottom: 1px solid blue;
      line-height:20px;
      overflow:auto;
      overflow-x:hidden;
      }
      .sendWindow{
      width: 100%;
      height: 200px;
      }
      .sendChatValue{ width: 90%;
      height: 40px; !