使用RethinkDB与SpringBoot 搭建一个简单的聊天
来源:互联网 发布:2016年淘宝交易额 编辑:程序博客网 时间:2024/06/09 22:09
最近项目有需要用到RethinkDB,故而在网上查询些资料,本文主要借鉴https://geowarin.github.io/spring-boot-and-rethinkdb.html 通过搭建一个聊天应用程序来学习RethinkDB.
RethinkDB 是什么?官网上的介绍是:RethinkDB is the open-source, scalable database that makes building realtime apps dramatically easier.
一、搭建rethinDB服务端
1、访问RethinkDB官网下载服务端:https://www.rethinkdb.com/docs/install/windows/ 我是在win7环境下搭建的,所以我下载的是windows版本的,如果各位是其他版本的,也可以在https://www.rethinkdb.com/docs/install/ 里面选择对应服务器的版本。
2、启动服务端:将下载好的rethinkdb-2.3.6.zip 解压后,双击rethinkdb.exe 及运行rethinkDB服务端了,默认相关数据是存储在当前目录的,文件名是rethinkdb_data。如果需要保存至指定目录是,需要用命令行执行如:C:\Users\Administrator\Desktop\rethinkdb-2.3.6>rethinkdb.exe -d f:\rethinkDB\data 前提是那个文件夹是存在的。 运行完毕以后,出现Server ready, 即代表服务启动完毕。打开浏览器:localhost:8080 看到如下dashboard 说明启动成功了
二、编写SpringBoot工程
1、增加maven依赖 主要包含springboot依赖包、org.webjars依赖包、以及RethinkDB的客户端依赖包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>1.3.3.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>1.3.3.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>1.3.3.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>1.3.3.RELEASE</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.0.0-alpha1</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>sockjs-client</artifactId><version>1.0.0</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>stomp-websocket</artifactId><version>2.3.3</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>momentjs</artifactId><version>2.11.1</version></dependency><dependency><groupId>com.rethinkdb</groupId><artifactId>rethinkdb-driver</artifactId><version>2.3.3</version></dependency>2、RethinkDB每个动作都是需要一个connection,所以先见一个工厂
public class RethinkDBConnectionFactory { private String host; private int port; public RethinkDBConnectionFactory(String host,int port) { this.host = host; this.port = port; } public Connection createConnection() { return RethinkDB.r.connection().hostname(host).port(port).connect(); }}
配置类:
@Configurationpublic class RethinkDBConfiguration { // connect to docker public static final String DBHOST = "127.0.0.1"; public static final int DBPORT = 28015; @Bean public RethinkDBConnectionFactory connectionFactory() { return new RethinkDBConnectionFactory(DBHOST,DBPORT); } @Bean DbInitializer dbInitializer() { return new DbInitializer(); }}
3、初始化DB,createDb 主要是rethinkDB的api,如果不熟悉可以,看看https://www.rethinkdb.com/docs/guide/java/ 里面的api入门使用
public class DbInitializer implements InitializingBean { @Autowired private RethinkDBConnectionFactory connectionFactory; @Autowired private ChatChangesListener chatChangesListener; private static final RethinkDB r = RethinkDB.r; public void afterPropertiesSet() throws Exception { createDb(); chatChangesListener.pushChangesToWebSocket(); } private void createDb() { Connection connection = connectionFactory.createConnection(); List<String> dbList = r.dbList().run(connection); if (!dbList.contains("chat")) { r.dbCreate("chat").run(connection); } List<String> tables = r.db("chat").tableList().run(connection); if (!tables.contains("messages")) { r.db("chat").tableCreate("messages").run(connection); r.db("chat").table("messages").indexCreate("time").run(connection); } }}
4、聊天控制器
GET从DB中删除最后20条消息
POST发出新消息
@RestController@RequestMapping("/chat")public class ChatController { protected final Logger log = LoggerFactory.getLogger(ChatController.class); private static final RethinkDB r = RethinkDB.r; @Autowired private RethinkDBConnectionFactory connectionFactory; @RequestMapping(method = RequestMethod.POST) public ChatMessage postMessage(@RequestBody ChatMessage chatMessage) { chatMessage.setTime(OffsetDateTime.now()); HashMap run = r.db("chat").table("messages").insert(chatMessage) .run(connectionFactory.createConnection()); log.info("Insert {}", run); return chatMessage; } @RequestMapping(method = RequestMethod.GET) public List<ChatMessage> getMessages() { List<ChatMessage> messages = r.db("chat").table("messages") .orderBy().optArg("index", r.desc("time")) .limit(20) .orderBy("time") .run(connectionFactory.createConnection(), ChatMessage.class); return messages; }}ChatMessage 实体类
public class ChatMessage { private String message; private String from; private OffsetDateTime time; public ChatMessage() { } public ChatMessage(String message, String from, OffsetDateTime time) { this.message = message; this.from = from; this.time = time; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public OffsetDateTime getTime() { return time; } public void setTime(OffsetDateTime time) { this.time = time; }}监听数据库表的更新,会将更改的数据通过Websocket推送
@Servicepublic class ChatChangesListener { protected final Logger log = LoggerFactory.getLogger(ChatChangesListener.class); private static final RethinkDB r = RethinkDB.r; @Autowired private RethinkDBConnectionFactory connectionFactory; @Autowired private SimpMessagingTemplate webSocket; @Async public void pushChangesToWebSocket() { Cursor<ChatMessage> cursor = r.db("chat").table("messages").changes() .getField("new_val") .run(connectionFactory.createConnection(), ChatMessage.class); while (cursor.hasNext()) { ChatMessage chatMessage = cursor.next(); log.info("New message: {}", chatMessage.getMessage()); webSocket.convertAndSend("/topic/messages", chatMessage); } }}配置Websocket
@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); } public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chatWS").withSockJS(); }}
前端:index
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Spring boot and Rethinkdb Chat</title> <link rel="stylesheet" href="css/main.css"></head><body><div id="container"> <div id="chat"> <ul id="messages"> </ul> <form onsubmit="sendMessage(); return false;"> <div class="chat-message clearfix"> <input name="message-to-send" autocomplete="off" id="messageInput" placeholder="Type your message" /> <button type="submit">Send</button> </div> </form> </div></div><script src="webjars/jquery/3.0.0-alpha1/jquery.js"></script><script src="webjars/sockjs-client/1.0.0/sockjs.js"></script><script src="webjars/stomp-websocket/2.3.3/stomp.js"></script><script src="webjars/momentjs/2.11.1/moment.js"></script><script src="js/main.js"></script></body></html>
CSS样式main.css
*, *:before, *:after { box-sizing: border-bo}ol, ul { list-style: none;}body { background: #C5DDEB; font: 14px/20px "Lato", Arial, sans-serif; padding: 40px 0; color: white;}#container { margin: 0 auto; width: 750px; background: #444753; border-radius: 5px;}#chat { width: 750px; float: left; background: #F2F5F8; border-top-right-radius: 5px; border-bottom-right-radius: 5px; color: #434651;}#messages { padding: 30px 30px 20px; border-bottom: 2px solid white; overflow-y: scroll; height: 575px;}.message-data { margin-bottom: 15px;}.message-data-time { color: #92959E; padding-left: 6px;}.message { color: white; padding: 10px; font-size: 16px; border-radius: 7px; margin-bottom: 6px; width: 90%; position: relative;}.message:after { bottom: 100%; left: 7%; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; border: 10px solid transparent; border-bottom-color: #86BB71; margin-left: -10px;}.my-message { background: #86BB71;}.other-message { background: #6C86D2;}.other-message:after { border-bottom-color: #6C86D2; left: 93%;}.chat-message { padding: 30px;}#messageInput { width: 100%; border: none; padding: 10px 20px; font: 14px/22px "Lato", Arial, sans-serif; margin-bottom: 10px; border-radius: 5px; resize: none;}button { float: right; color: #94C2ED; font-size: 16px; text-transform: uppercase; border: none; cursor: pointer; font-weight: bold; background: #F2F5F8;}button:hover { color: #7fa9ce;}.align-left { text-align: left;}.align-right { text-align: right;}.float-right { float: right;}.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0;}JS main.js
var userName = window.prompt("Enter your name", "some user");//var userName = "lol";function post(url, data) { return $.ajax({ type: 'POST', url: url, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, data: JSON.stringify(data) })}function appendMessage(message) {var time = message.time; var fromNow = time.year +"-" + time.monthValue + "-" + time.dayOfMonth + " " + time.hour + ":" + time.minute + ":" +time.second; var $message = $(`<li class="clearfix"> <div class="message-data ${message.from == userName ? 'align-left': 'align-right'}"> <span class="message-data-name">${message.from}</span> <span class="message-data-time">${fromNow}</span> </div> <div class="message ${message.from == userName ? 'my-message': 'other-message float-right'}"> ${message.message} </div> </li>`); var $messages = $('#messages'); $messages.append($message); $messages.scrollTop($messages.prop("scrollHeight"));}function getPreviousMessages() { $.get('/chat').done(messages => messages.forEach(appendMessage));}function sendMessage() { var $messageInput = $('#messageInput'); if($messageInput.val() ==null || $messageInput.val() ==""){ alert("不允许发空消息"); return; } var message = {message: $messageInput.val(), from: userName}; $messageInput.val(''); post('/chat', message);}function onNewMessage(result) { var message = JSON.parse(result.body); appendMessage(message);}function connectWebSocket() { var socket = new SockJS('/chatWS'); stompClient = Stomp.over(socket); //stompClient.debug = null; stompClient.connect({}, (frame) => { console.log('Connected: ' + frame); stompClient.subscribe('/topic/messages', onNewMessage); });}getPreviousMessages();connectWebSocket();resources的目录结构为:
三、启动客户端 必须使用jdk1.8
直接执行BootRethinkdbApplication的main方法,然后访问localhost:8093/index.html
具体的github的请见
https://github.com/StephenXiong/rethinkdb-boot
- 使用RethinkDB与SpringBoot 搭建一个简单的聊天
- 快速搭建一个简单的springboot项目
- 初探SpringBoot,简单搭建一个SpringBoot框架
- SpringBoot WebSocket 实现简单的聊天功能
- [转]一个高性能的NoSQL: RethinkDB
- 在idea中简单的搭建一个springboot工程
- 如何使用TCP/IP与服务器进行通信-一个简单的聊天程序
- 如何使用TCP/IP与服务器进行通信-一个简单的聊天程序
- 简单的springboot项目搭建
- 简单的SpringBoot工程搭建
- 一个简单的聊天代码
- 一个简单的聊天程序
- 使用UDP实现一个简单的聊天程序。
- 使用SignalR建一个简单的web聊天Demos
- 使用ServerSocket、Socket创建一个简单的服务聊天程序
- 使用最新Netty实现一个简单的聊天程序
- 使用最新Netty实现一个简单的聊天程序
- 一个简单的Springboot项目
- 时间戳,字符串转换小工具
- #include<>和#include""的区别
- ESP8266系列 远程LED开关操作-综述
- jupyter notebook 使用记录
- 文章标题
- 使用RethinkDB与SpringBoot 搭建一个简单的聊天
- MFC关于身份证有效性的判定
- flip、transpose 图像翻转镜像
- 有序数组合并
- ElasticSearch常用的基本查询语句详解
- FFmpeg命令行工具的使用
- FPGA静态时序分析模型——寄存器到寄存器
- 欢迎使用CSDN-markdown编辑器
- innosetup卸载删除文件