springboot+kafka+mysql聊天demo(简单案例 )

kafka安装请参考官网即可,本案例中使用2.8.1版本

mysql只负责记录

pom依赖

<dependencies>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- 阿里的json解析依赖 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-parameter-names</artifactId>
        </dependency>
        
		<!-- 下边这个springboot自动创建实例 -->
		<dependency>
		    <groupId>org.springframework.kafka</groupId>
		    <artifactId>spring-kafka</artifactId>
		    <version>2.8.1</version>
		</dependency>
		<!-- mysql -->
		<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.14</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        
        <dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>fastjson</artifactId>
		    <version>1.2.41</version>
		</dependency>
	  </dependencies>

application.yml文件

server: 
  port: 80
spring:
  datasource: 
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/wy?&serverTimezone=GMT%2B8&characterEncoding=utf-8
    username: root
    password: 123456
  jpa: 
    database: MYSQL
    show-sql: true
    hibernate: 
      ddl-auto: update
      naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
    properties: 
      hibernate: 
        dialect:org.hibernate.dialect.MySQL5Dialect
  kafka:
    #消息监听的主体(自己用户的id)
    topicsUser: 32882
    #Kafka服务器地址
    bootstrap-servers: 127.0.0.1:9092
    producer:
      #设置数据value的序列化处理类
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
    consumer:
      #设置数据value的反序列化处理类
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

AppKafka.java启动主文件

package cn.com.wy.kafka;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.scheduling.annotation.EnableScheduling;

import cn.com.wy.kafka.chatInterface.LoginInteface;
import cn.com.wy.kafka.chatInterface.MainInterface;
import cn.com.wy.kafka.utils.SpringUtil;
import cn.com.wy.kafka.utils.YamlUtils;

/**
 * Hello world!
 *
 */
@EnableScheduling
@SpringBootApplication
@Import({SpringUtil.class,YamlUtils.class})
public class AppKafka 
{
    public static void main( String[] args ) throws Exception
    {	
    	System.setProperty("java.awt.headless", "false");
    	SpringApplication.run(AppKafka.class, args);
    	
    	new MainInterface("32882");
    }
}

MainInterface.java主界面

package cn.com.wy.kafka.chatInterface;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;

import cn.com.wy.kafka.service.producerService;
import cn.com.wy.kafka.utils.SpringUtil;

/**
 * 聊天主界面
 * @author wy
 *
 */
public class MainInterface {
	@Autowired
	private JdbcTemplate jdbc = SpringUtil.getBean(JdbcTemplate.class);;
	//登录人id
	@Value("${spring.kafka.topicsUser}")
	private String ownUserId;
	//发送业务层
	private producerService  product=SpringUtil.getBean(producerService.class);
	
	private JFrame f = new JFrame("聊天");
	
	private static JTextPane jtp = new JTextPane();
	JScrollPane jsp = new JScrollPane(jtp);
	
	//面板
	JPanel jp = new JPanel();
	//文本框的长度
	JTextField jtf = new JTextField(25); 
	 //按钮
	JButton jb = new JButton("发送");
	
	
	public MainInterface(String receiveUserId) {
		jtp.setEditable(false);
		f.add(jsp);
		jp.add(jtf);
		jp.add(jb);
		
		//注意:需要将滚动条域面板全部添加到窗体中
		f.add(jsp, BorderLayout.CENTER);
		f.add(jp, BorderLayout.SOUTH);//窗体的下面(南部)

		//注意:需要设置 标题、大小、位置、关闭,是否可见
		f.setTitle("聊天框 服务端");
		f.setSize(400, 300);
		f.setLocation(300, 300);
		//窗体关闭,程序就退出
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setVisible(true);
		
		
		//按钮绑定事件
		jb.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				sendEdit();
				 //发送数据
		    	product.send(jtf.getText(), receiveUserId);
		    	
			}
		});
		//文本绑定事件
		jtf.addKeyListener(new KeyListener() {
			@Override
			public void keyTyped(KeyEvent e) {
			}
			@Override
			public void keyReleased(KeyEvent e) {
			}
			
			@Override
			public void keyPressed(KeyEvent e) {
				 //回车键
			    if (e.getKeyCode() == KeyEvent.VK_ENTER) {//判断是不是回车键
			    	sendEdit();
			        //发送数据
			    	product.send(jtf.getText(), receiveUserId);
			    }
			}
		});
	}
	
	public  void sendEdit(){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateTime = df.format(new Date());
        String str = dateTime+"  我"+":"+"\n"+jtf.getText();
        setDocs(str,Color.red,false,14);
	}
	
	//编辑文本信息
	public static void edit(String message){
//		jta.append("\n"+message);
		setDocs(message,Color.BLUE,true,14);
	}
	
	public static void insert(String str, AttributeSet attrSet) {
		Document doc = jtp.getDocument();
		str = "\n " + str ;
		try {
			doc.insertString(doc.getLength(), str, attrSet);
		}
		catch (BadLocationException e) {
			System.out.println( "BadLocationException: " + e);
		}
	}

	//设置文本
	public static void setDocs(String str,Color col,boolean bold,int fontSize) {
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setForeground(attrSet, col);
		//颜色
		if(bold==true){
			StyleConstants.setBold(attrSet, true);
		}//字体类型
		StyleConstants.setFontSize(attrSet, fontSize);
		
		StyleConstants.setAlignment(attrSet, StyleConstants.ALIGN_RIGHT);
		StyleConstants.setRightIndent(attrSet, 2);
		//字体大小
		insert(str, attrSet);
	}
}

producerService.java发送消息

package cn.com.wy.kafka.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.transaction.Transactional;

import org.apache.kafka.clients.producer.ProducerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import cn.com.wy.kafka.entity.RecordEntity;
import cn.com.wy.kafka.utils.YamlUtils;

import com.alibaba.fastjson.JSONObject;

/**
 * 发送消息实现层
 * @author Administrator
 *
 */
@Service
public class producerService {
	@Autowired
	private JdbcTemplate jdbc;
	@Autowired
	private KafkaTemplate<String,String> kafkaTemplate;
	@Value("${spring.kafka.topicsUser}")
	private String ownUserId;
	
	/**
	 * 记录保存
	 * @param record
	 */
	@Transactional
	public void save(RecordEntity record,String dateTime){
		String uuid = UUID.randomUUID().toString().replace("-", "");
		record.setId(uuid);
		jdbc.execute("insert into `info_record` (`id`, `send_user_id`, `receive_user_id`, `message`, `create_time`, `delete_flg`) values('"+uuid+"','"+record.getSendUserId()+"','"+record.getReceiveUserId()+"','"+record.getMessage()+"','"+dateTime+"','"+record.getDeleteFlg()+"');");
	}

	/**
	 * 发送
	 * @param message 内容
	 * @param userId 接收人id
	 */
	@Transactional
	 public void send(String message,String userId) {
    	try{
    		//需要根据用户id查询用户名称
    		String userName = "";
    		Map<String,String> map = new HashMap<String, String>();
	        map.put("senUserId", ownUserId);
	        map.put("message", message);
	        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String dateTime = df.format(new Date());
			map.put("time", dateTime);
			
			String json = JSONObject.toJSONString(map);
    		ProducerRecord<String, String> record = new ProducerRecord(userId, json);
	        kafkaTemplate.send(record);
	        //写入记录表,方便后期查询使用
	        RecordEntity record1 = new RecordEntity();
	        record1.setMessage(json);
	        record1.setReceiveUserId(userId);
	        record1.setSendUserId(ownUserId);
	        save(record1,dateTime);
    	}catch(Exception e){
    		
    	}
    	 
    }
}

consumerController.java监听接收消息

package cn.com.wy.kafka;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
import org.springframework.kafka.listener.ConsumerSeekAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import cn.com.wy.kafka.chatInterface.MainInterface;
import cn.com.wy.kafka.utils.SpringUtil;
import cn.com.wy.kafka.utils.YamlUtils;

import com.alibaba.fastjson.JSONObject;
/**
 * 接收监听层
 * @author wy
 *
 */
@Component
public class consumerController implements ConsumerSeekAware{
	@Autowired
	JdbcTemplate jdbc;
	 
	Logger log = LoggerFactory.getLogger(consumerController.class);
	
	/**
	 * 消息监听接口
	 * @param record
	 */
	@KafkaListener(topics = "${spring.kafka.topicsUser}",groupId="wy")
    public void listen(ConsumerRecord<?, ?> record) {
        Optional<?> kafkaMessage = Optional.ofNullable(record.value());
        if (kafkaMessage.isPresent()) {
        	String str1 =  (String) kafkaMessage.get();
        	Map<String,String> message = JSONObject.parseObject(str1,Map.class);
            //发送人id
            String senUserId = message.get("senUserId");
            //查询发送人名称
            List<Map<String, Object>> queryForList = jdbc.queryForList("SELECT iu.user_name as name FROM info_user iu WHERE iu.id='"+senUserId+"'");
            
            String str = message.get("message");
            String time = message.get("time");
            if(queryForList!=null && queryForList.size()>0){
            	String name = (String) queryForList.get(0).get("name");
            	if(!StringUtils.isEmpty(name)){
            		str=time+"  "+name+":"+str;
            	}
            }
            MainInterface.edit("\n"+str);
        }
    }
}

下边是所需实体,如不需要数据库可以屏蔽掉,目前 数据库只作为记录,后期会调整为es

UserEntity.java

package cn.com.wy.kafka.entity;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "info_user")
public class UserEntity {
	/**
	 * 用户id
	 */
	@Id
    @GeneratedValue(generator = "JDBC")
	private String id;
	/**
	 * 用户名
	 */
	@Column(name = "user_name")
	private String userName;
	/**
	 * 用户昵称
	 */
	@Column(name = "user_nickname")
	private String userNickname;
	/**
	 * 删除标识,0未删除,1已删除
	 */
	@Column(name = "delete_flg")
	private int deleteFlg;
	/**
	 * 在线状态,0未在线,1已在线
	 */
	@Column(name = "online_status")
	private int onlineStatus;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserNickname() {
		return userNickname;
	}
	public void setUserNickname(String userNickname) {
		this.userNickname = userNickname;
	}
	public int getDeleteFlg() {
		return deleteFlg;
	}
	public void setDeleteFlg(int deleteFlg) {
		this.deleteFlg = deleteFlg;
	}
	public int getOnlineStatus() {
		return onlineStatus;
	}
	public void setOnlineStatus(int onlineStatus) {
		this.onlineStatus = onlineStatus;
	}
	
	
}

RecordEntity.java

package cn.com.wy.kafka.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "info_record")
public class RecordEntity {
	/**
	 * id
	 */
	@Id
    @GeneratedValue(generator = "JDBC")
	private String id;
	
	/**
	 * 发送用户id
	 */
	@Column(name = "send_user_id")
	private String sendUserId;
	/**
	 * 接收用户id
	 */
	@Column(name = "receive_user_id")
	private String receiveUserId;
	/**
	 * 信息
	 */
	@Column(name = "message")
	private String message;
	/**
	 * 创建时间
	 */
	@Column(name = "create_time")
	private Date createTime;
	/**
	 * 删除标识,0未删除,1已删除
	 */
	@Column(name = "delete_flg")
	private int deleteFlg;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getSendUserId() {
		return sendUserId;
	}
	public void setSendUserId(String sendUserId) {
		this.sendUserId = sendUserId;
	}
	public String getReceiveUserId() {
		return receiveUserId;
	}
	public void setReceiveUserId(String receiveUserId) {
		this.receiveUserId = receiveUserId;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	public int getDeleteFlg() {
		return deleteFlg;
	}
	public void setDeleteFlg(int deleteFlg) {
		this.deleteFlg = deleteFlg;
	}
	
	
}

数据库脚本

CREATE DATABASE /*!32312 IF NOT EXISTS*/`wy` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `wy`;

/*Table structure for table `info_record` */

CREATE TABLE `info_record` (
  `id` varchar(32) NOT NULL COMMENT '主键',
  `send_user_id` varchar(32) DEFAULT NULL COMMENT '发送用户id',
  `receive_user_id` varchar(32) DEFAULT NULL COMMENT '接收用户id',
  `message` text COMMENT '内容',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间',
  `delete_flg` int(11) DEFAULT NULL COMMENT '撤回',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='聊天记录表';

/*Table structure for table `info_user` */

CREATE TABLE `info_user` (
  `id` varchar(32) NOT NULL COMMENT '主键',
  `user_name` varchar(64) DEFAULT NULL COMMENT '用户名称',
  `user_nickname` varchar(64) DEFAULT NULL COMMENT '昵称',
  `delete_flg` int(11) DEFAULT NULL COMMENT '删除标识',
  `online_status` int(11) DEFAULT NULL COMMENT '在线状态',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值