Logux:构建实时协作应用的利器
项目介绍
Logux 是一个强大的 WebSocket 客户端/服务器框架,专为构建实时协作应用而设计。无论您是在开发多人协作的文档编辑器,还是需要实时更新的社交应用,Logux 都能为您提供所需的功能。通过结合现代的反应式客户端架构和 WebSocket 技术,Logux 能够确保多个用户之间的操作顺序一致,并提供实时更新、乐观 UI 和离线优先的支持。
项目技术分析
Logux 的核心技术包括:
- CRDT(Conflict-free Replicated Data Types):Logux 借鉴了 CRDT 的思想,能够在多个用户同时编辑时自动解决冲突,确保数据的一致性。
- WebSocket:通过 WebSocket 技术,Logux 实现了客户端和服务器之间的实时通信,确保用户能够立即看到其他用户的更改。
- Redux 架构:Logux 与 Redux 深度集成,能够同步 Redux 操作,确保操作顺序在所有客户端和服务器上保持一致。
- IndexedDB:Logux 使用 IndexedDB 存储 Redux 操作,支持离线操作,并在网络恢复时自动同步数据。
项目及技术应用场景
Logux 适用于以下场景:
- 协作应用:如多人同时编辑的文档、白板应用等,Logux 的 CRDT 特性能够确保多人协作时的数据一致性。
- 实时应用:如社交网络、在线游戏等,Logux 的实时更新功能能够让用户立即看到其他用户的操作。
- 离线优先应用:如移动应用、地铁应用等,Logux 的离线优先特性能够确保用户在网络不稳定的情况下仍能正常使用应用。
项目特点
- 实时协作:Logux 通过 CRDT 技术解决了多人协作时的冲突问题,确保数据的一致性。
- 乐观 UI:Logux 支持乐观 UI,能够在不等待服务器响应的情况下更新用户界面,提升用户体验。
- 离线优先:Logux 使用 IndexedDB 存储操作,支持离线操作,并在网络恢复时自动同步数据。
- 无供应商锁定:Logux 可以在任何云环境中使用,并且支持任何数据库,避免了供应商锁定的问题。
- 轻量级:Logux 仅在客户端增加 9 KB 的 JS 包大小,对性能影响极小。
示例代码
客户端示例
React 客户端
import { syncMapTemplate } from '@logux/client'
export type TaskValue = {
finished: boolean
text: string
authorId: string
}
export const Task = syncMapTemplate<TaskValue>('tasks')
export const ToDo = ({ userId }) => {
const tasks = useFilter(Task, { authorId: userId })
if (tasks.isLoading) {
return <Loader />
} else {
return <ul>
{tasks.map(task => <li>{task.text}</li>)}
</ul>
}
}
Vue 客户端
<template>
<h1 v-if="isSubscribing">Loading</h1>
<div v-else>
<h1>{{ counter }}</h1>
<button @click="increment"></button>
</div>
</template>
<script>
import { computed } from 'vue'
import { useStore, useSubscription } from '@logux/vuex'
export default {
setup () {
let store = useStore()
let counter = computed(() => store.state.counter)
let isSubscribing = useSubscription(['counter'])
function increment () {
store.commit.sync({ type: 'INC' })
}
return {
counter,
increment,
isSubscribing
}
}
}
</script>
服务器示例
addSyncMap(server, 'tasks', {
async access (ctx, id) {
const task = await Task.find(id)
return ctx.userId === task.authorId
},
async load (ctx, id, since) {
const task = await Task.find(id)
if (!task) throw new LoguxNotFoundError()
return {
id: task.id,
text: ChangedAt(task.text, task.textChanged),
finished: ChangedAt(task.finished, task.finishedChanged),
}
},
async create (ctx, id, fields, time) {
await Task.create({
id,
authorId: ctx.userId,
text: fields.text,
textChanged: time,
finished: fields.finished,
finishedChanged: time
})
},
async change (ctx, id, fields, time) {
const task = await Task.find(id)
if ('text' in fields) {
if (task.textChanged < time) {
await task.update({
text: fields.text,
textChanged: time
})
}
}
if ('finished' in fields) {
if (task.finishedChanged < time) {
await task.update({
finished: fields.finished,
finishedChanged: time
})
}
}
}
async delete (ctx, id) {
await Task.delete(id)
}
})
总结
Logux 是一个功能强大且灵活的 WebSocket 框架,适用于各种需要实时协作和离线优先的应用场景。无论您是开发协作工具、社交应用还是移动应用,Logux 都能为您提供所需的技术支持。立即尝试 Logux,体验其强大的功能和卓越的性能吧!