一. 需求背景
     最近新接触一个需求,需要将kafka中的数据实时推送到前端展示。最开始想到的是前端轮询接口数据,但是无法保证轮询的频率和消费的频率完全一致,或造成数据缺失等问题。最终确定用利用WebSocket实现数据的实时推送。
 
二. websocket简介
     网上已经有好多介绍WebSocket的文章了,就不详细介绍了,这里只做简单介绍。 WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
 
三. 服务端实现
  1. pom文件
  这里需要引用三个依赖。第一个为WebSocket需要的依赖,另外两个为kafka的依赖
 
 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>person</groupId>
<artifactId>wbSocketkafka</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<!-- webSocket所需依赖 -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!-- kafka 所需依赖 -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.9.2</artifactId>
<version>0.8.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
</project>

  2. webSocket服务端实现

 //此处定义接口的uri
@ServerEndpoint("/wbSocket")
public class WebSocket {
private Session session;
public static CopyOnWriteArraySet<WebSocket> wbSockets = new CopyOnWriteArraySet<WebSocket>(); //此处定义静态变量,以在其他方法中获取到所有连接 /**
* 建立连接。
* 建立连接时入参为session
*/
@OnOpen
public void onOpen(Session session){
this.session = session;
wbSockets.add(this); //将此对象存入集合中以在之后广播用,如果要实现一对一订阅,则类型对应为Map。由于这里广播就可以了随意用Set
System.out.println("New session insert,sessionId is "+ session.getId());
}
/**
* 关闭连接
*/
@OnClose
public void onClose(){
wbSockets.remove(this);//将socket对象从集合中移除,以便广播时不发送次连接。如果不移除会报错(需要测试)
System.out.println("A session insert,sessionId is "+ session.getId());
}
/**
* 接收前端传过来的数据。
* 虽然在实现推送逻辑中并不需要接收前端数据,但是作为一个webSocket的教程或叫备忘,还是将接收数据的逻辑加上了。
*/
@OnMessage
public void onMessage(String message ,Session session){
System.out.println(message + "from " + session.getId());
} public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
}

  3. kafka消费者实现

 public class ConsumerKafka extends Thread {

     private KafkaConsumer<String,String> consumer;
private String topic = "kafkaTopic"; public ConsumerKafka(){ } @Override
public void run(){
//加载kafka消费者参数
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "ytna");
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
props.put("session.timeout.ms", "15000");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
//创建消费者对象
consumer = new KafkaConsumer<String,String>(props);
consumer.subscribe(Arrays.asList(this.topic));
//死循环,持续消费kafka
while (true){
try {
//消费数据,并设置超时时间
ConsumerRecords<String, String> records = consumer.poll(100);
//Consumer message
for (ConsumerRecord<String, String> record : records) {
//Send message to every client
for (WebSocket webSocket :wbSockets){
webSocket.sendMessage(record.value());
}
}
}catch (IOException e){
System.out.println(e.getMessage());
continue;
}
}
} public void close() {
try {
consumer.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
} //供测试用,若通过tomcat启动需通过其他方法启动线程
public static void main(String[] args){
ConsumerKafka consumerKafka = new ConsumerKafka();
consumerKafka.start();
}
}
 
P.S. 需要注意的是WebSocket对tomcat版本是有要求的,笔者使用的是7.0.7.8。
 
四. 前端简单实现
 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket client</title>
<script type="text/javascript">
var socket;
if (typeof (WebSocket) == "undefined"){
alert("This explorer don't support WebSocket")
} function connect() {
//Connect WebSocket server
socket =new WebSocket("ws://127.0.0.1:8080/wbSocket");
//open
socket.onopen = function () {
alert("WebSocket is open");
}
//Get message
socket.onmessage = function (msg) {
alert("Message is " + msg);
}
//close
socket.onclose = function () {
alert("WebSocket is closed");
}
//error
socket.onerror = function (e) {
alert("Error is " + e);
}
} function close() {
socket.close();
} function sendMsg() {
socket.send("This is a client message ");
}
</script>
</head>
<body>
<button onclick="connect()">connect</button>
<button onclick="close()">close</button>
<button onclick="sendMsg()">sendMsg</button>
</body>
</html>
 
五. 结语
     以上基本可以实现将kafka数据实时推送到前端。这是笔者第一篇笔记,不足之处请指出、谅解。
     源码:https://github.com/youtNa/webSocketkafka
   引用:1. webSocket百度百科

WebSocket和kafka实现数据实时推送到前端的更多相关文章

  1. SpringBoot2.0整合WebSocket,实现后端数据实时推送!

    之前公司的某个系统为了实现推送技术,所用的技术都是Ajax轮询,这种方式浏览器需要不断的向服务器发出请求,显然这样会浪费很多的带宽等资源,所以研究了下WebSocket,本文将详细介绍下. 一.什么是 ...

  2. Springboot:SpringBoot2.0整合WebSocket,实现后端数据实时推送!

    一.什么是WebSocket? B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不 ...

  3. WebSocket实现站内消息实时推送

    关于WebSocket WebSocket是HTML5 开始提供的一种在单个TCP连接上进行全双工通讯的协议.什么是全双工?就是在同一时间可以发送和接收消息,实现双向通信,比如打电话.WebSocke ...

  4. Javascript中数据实时推送

    数据变化后前端需要更新,有几种方式:(参考http://www.xiaocai.name/post/cf1f9_7b6507) .利用setInterval函数,每隔n秒去异步拉取数据.对数据实时性要 ...

  5. 用node.js(socket.io)实现数据实时推送

    在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格.实现的方式有很多,比如: 1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时) 2. AJAX轮询方式方式推 ...

  6. Spring MVC 实现web Socket向前端实时推送数据

    最近项目中用到了webSocket服务,由后台实时向所有的前端推送消息,前端暂时是不可以发消息给后端的,数据的来源是由具体的设备数据收集器收集起来,然后通过socket推送给后端,后端收到数据后,再将 ...

  7. springboot搭建一个简单的websocket的实时推送应用

    说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...

  8. HTML5 WebSocket 实时推送信息测试demo

    测试一下HTML5的websocket功能,实现了客户端→服务器实时推送信息到客户端,包括推送图片: websocket实现MessageInbound类 onTextMessage()/onBina ...

  9. 关于 实时推送技术--WebSocket的 知识分享

    今天学习了关于WebSocket的知识,觉得挺有用的,在这记录一下,也和大家分享一下!!有兴趣的可以看看哦 WebSocket简介 Web领域的实时推送技术,也被称作Realtime技术.这种技术要达 ...

随机推荐

  1. Linux轻松使用vim

    VIM命令---Vi IMproved, a programmers text editor文本编辑 1>gedit   图形文本编辑工具 2>vim      字符界面的编辑工具 写脚本 ...

  2. 纯原生javascript实现分页效果

    随着近几年前端行业的迅猛发展,各种层出不穷的新框架,新方法让我们有点眼花缭乱. 最近刚好比较清闲,所以没事准备撸撸前端的根基javascript,纯属练练手,写个分页,顺便跟大家分享一下 functi ...

  3. ActiveMQ学习心得:连接池的简单实现和模板模式的应用

    一.安装activemq 下载地址:https://archive.apache.org/dist/activemq/5.13.0/apache-activemq-5.13.0-bin.zip 下载完 ...

  4. angular 实现时间段选择组件

    前段时间公司有个后台项目需要使用一个选择时间段的组件,看了一下就自己写了一下,用angular写这种插件还是很简单的. 先看看最终是什么样子的: 功能是用户可以选择任意时间段,鼠标可以拖动任意的一周的 ...

  5. 由CODEVS笨小猴1053引发的一些思考

    #include<cstdio> #include<cstring> ]; ]; int check(int n) { ||n==) ; ;m*m<=n;++m) ) ; ...

  6. CI Weekly #18 | flow.ci iOS 最佳实践出炉,正式支持 Git@OSC 构建

    如大家所期待,flow.ci 现已支持开源中国的代码仓库 - 码云,可以直接构建 Git@OSC 的项目了,点击创建项目-选择代码仓库-选择码云-绑定 OSChina 账户-选择要构建项目,教程看这里 ...

  7. ECMAScript6 规范

    本文探讨如何将ES6的新语法,运用到编码实践之中,与传统的JavaScript语法结合在一起,写出合理的.易于阅读和维护的代码. 多家公司和组织已经公开了它们的风格规范,具体可参阅http://jsc ...

  8. Unity 消息发送机制 解析

    该博客,只为解析,解析,解析,已经整理好,已经整理好,已经整理好.代码核心原理套用网上最流行的那一套,也是最常用游戏开发适用的消息机制.这里面加上自己的一些优化,极大的修正(哈哈),实测,没问题.万一 ...

  9. 为程序猿正名,MM们,你们为什么要找一个程序猿男票?【原创】

    前言 免责声明:这篇文章关于什么?六一儿童节马上就要到了,作为一个前端攻城师,自我感觉效率还可以,老早已把任务搞完,页面布局和前端编码高效按时交付,呵呵.趁有时间,写写文章娱乐一下.MM们,请不要拿起 ...

  10. redis安装学习

    Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串.哈希表.列表.集合.有序集合,位图,hyperloglogs等数据类型.内置复制.Lu ...