在开发业务中,经常需要服务器与客户端的消息交互,有的业务需要等待服务器处理并且实时看到处理进度,即看到服务器的处理进度,本文以spring boot来讲解,其他的语言也可以类推。
思路:
当浏览器发送请求时,与服务器建立http GET连接,此时保持连接不断开,服务器就可以主动发送消息给前端页面了。
代码:
@GetMapping("getmessage")
public void sendMsg(HttpServletResponse response) throws IOException{
response.setContentType("application/json;charset=utf-8");
while(true){
write(response,"测试"+"--------------------\n");
Thread.sleep(1000);
}
}
private void write(HttpServletResponse response,String content) throws IOException {
response.getWriter().write(content+"");
response.flushBuffer();
response.getWriter().flush();
}
通过运行以上代码,可以看到浏览器的地址栏一直处于加载中的状态(一直转圈圈),并且一直每隔1秒出现一个“测试———————————”的推送消息
至此,服务器与客户端保持长连接并且主动推送消息的基本功能已经实现。
进一步的扩展可以将此机制应用到聊天等业务场景中,即客户端与客户端通信,都与服务器保持get长连接以接收消息,发送消息只需要进行一个post请求就可以。
而while循环就需要去请求公共一个内存变量才能保证系统的稳定性(while一直去轮询数据库是不现实的)。Spring Boot有一个共享变量的类:
org.springframework.context.ApplicationContext;
在发送post消息时,将最新的一条消息保存到publishEvent中,
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
@Service
public class GetMessageImp {
@Autowired
private ApplicationContext ac;
public void addMessage(String msg) {
Message messages = new Message();
messages.setContent(dirid);
//System.out.println("接收到消息"+msg);
ac.publishEvent(messages);
}
}
此时通过Spring Boot提供的事件监听方法就可以获取到post上传上来的消息:
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class MsgServiceImp {
private String NewMessage = "";
@EventListener
public void sendMsg(Message message) {
System.out.println("发送消息" );
NowMessage = String.valueOf(message);
}
public String getNewMessage(){
return NewMessage;
}
}
当有新的post消息上来时,调用addMessage方法,@EventListener就会监听到,将接收到的最新一条消息保存到变量NewMessage中,然后while循环不断的访问这个变量是否有变化,有则推送,无则不推送,直到有新的post请求消息上来时,NewMessage变量才会变化,while也才会再次向客户端推送消息。
本文主要用到两个方法:
response.getWriter().write(content+"");//向客户端推送消息
@EventListener//监听接收到的客户端消息
END