🕊️ The world's most advanced open source instant messaging engine for 100K~10M concurrent users https://turms-im.github.io/docs

Overview

简体中文

What is Turms

Turms is the most advanced open-source instant messaging engine for 100K~10M concurrent users in the world. Please refer to Turms Documentation (no English version for now) for details.

Playground

(Version of demo servers: ghcr.io/turms-im/turms-admin:latest, ghcr.io/turms-im/turms-gateway:latest, ghcr.io/turms-im/turms-service:latest)

You can use any turms-client-(java/js/swift) implementation to send requests to turms-gateway and interact with other users.

In addition, Playground is set up automatically by just one command: ENV=dev docker-compose -f docker-compose.standalone.yml --profile monitoring up --force-recreate -d

Quick Start

Running the following commands to setup a minimum viable cluster (including turms-gateway, turms-service and turms-admin) and its dependent servers (MongoDB sharded cluster and Redis) automatically:

git clone --depth 1 https://github.com/turms-im/turms.git
cd turms
docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
docker-compose -f docker-compose.standalone.yml up --force-recreate

After the cluster is set up, you can visit turms-admin at http://localhost:6510, and enter the account and password (turms by default). If you log in successfully, it means that the cluster of Turms has been setup successfully.

You can also apply the Terraform modules provided by Turms to quickly purchase cloud services and set up a turms cluster (uses spot instances by default). After running terraform apply, wait for about 3~15 minutes (Alibaba Cloud ECS is slow to pull ghcr images), and then visit http://<public IP>:6510, if you can access turms-admin, it means that the turms cluster has been set up successfully.

(Note: The following commands will automatically purchase cloud services and deduct the corresponding fees from your account)

git clone --depth 1 https://github.com/turms-im/turms.git
cd turms/terraform/alicloud/playground
export ALICLOUD_ACCESS_KEY=<your_access_key>
export ALICLOUD_SECRET_KEY=<your_secret_key>
terraform init
terraform apply

Intro

The architecture of Turms depends on the fanout read design for creating inboxes (or message timelines), and Turms supports push model, pull model, and push-pull model to be aware of the changes of business data (For details, Business Data Change Awareness). Most of the other design details also come from commercial IM projects.

And compared to many projects with obsolete technology stacks, Turms is also the only open source IM solution that is based on modern architecture and modern technology and is suitable for medium to large scale applications.

In addition, architecture design is an art of trade-off. Some IM products take rich features as their slogan at the cost of no support for medium to large scale applications (they are only suitable for team communications). However, Turms takes extreme performance as the first priority and supports complete (rather than rich) IM features to support medium and large-scale applications. Please refer to Turms Schema Design and Observability for details.

When you need to compare Turms with other open source IM projects for features, you can first compare Turms with other open source IM projects based on the following features of Turms. Usually, you can find the differences between professional IM projects and amateur IM projects. In addition, under the chapter of Product Comparison, we also mentioned the shortcomings of the Turms project for your reference.

Note: The main disadvantage of the current Turms project is that it does not provide support for living/chat room. The technical implementation of the living/chat room is not difficult, but the product requirements, quality attribute requirements, and restrictive conditions are quite different from the scenarios of general social applications, so the first version of Turms does not provide support for it. In addition, Turms is also not suitable for small-scale enterprise communication scenarios. Using Turms for enterprise communication scenarios is using a sledgehammer to crack a nut, because enterprise communication emphasizes feature-rich rather than extreme performance, which is inconsistent with the goals of Turms, so their designs are also different. If you want to support enterprise communication scenarios, you need to develop based on Turms yourselves.

Business Features

  1. Support a complete set of IM features. Turms supports almost all IM features supported by commercial instant messaging products and no restrictions on business features. For example, Turms supports advanced features as unwanted words filtering (using Aho-Corasick automaton with double array trie). (The data analysis feature will be supported when turms-data is released in the future. Please refer to Turms Data Analysis for details)
  2. (Extensibility) Turms supports two approaches to extend: configuration properties and custom plugins. Of course, you can also modify the source code. For example, the plugin turms-plugin-minio based on turms-plugin is used to interact with MinIO server.
  3. (Flexibility) Turms provides hundreds of configuration properties for developers to meet various requirements. And most of the properties can be updated at the cluster level when the cluster is running without performance loss.

Common Architecture Features

  1. (Agility) Support updating Turms servers without the users' awareness of shutdown to support rapid iteration
  2. (Scalability) The Turms server is stateless to be scaled out; Support multi-active across data centers
  3. (Deployability) Support container deployment to facilitate integration (CI/CD) with cloud services. Turms provides three solutions for container deployment out of the box: docker image, docker-compose script, and Terraform module
  4. (Observability) Support relatively complete features of observability for business analysis and troubleshoot
  5. (Scalability) Support medium to large scale instant messaging applications, and there is no need to refactor even if the application becomes large from medium-scale (There is still a lot of optimization work to be done for large applications, but Turms servers are easy to upgrade)
  6. (Security) Support throttling API requests and blocking user/IP to resist most CC attacks
  7. (Simplicity) The Turms architecture is lightweight, which makes Turms easy to learn and redevelop. Please refer to Turms Architecture Design for details)
  8. Turms depends on the MongoDB sharded cluster to support request routing (such as read-write separation) for medium to large scale applications

Other Features

  1. Observable system (Please refer to Observability for details)

    • Log (for events): Turms provides three types of logs: monitoring log, business log, and statistics log

    • Metrics (for aggregable data). It reflects the real-time status of the system and business data

    • Tracing

    Note that the Turms server will provide more monitoring features that can be implemented efficiently as much as possible, but will not provide some common features that have a great impact on performance and are more suitable for third-party services to provide (such as DAU). For this kind of extended feature, you can implement them by offline or real-time analysis of the logs or metrics of Turms servers.

  2. Extreme performance We always try to archive extreme performance in the implementation of all business workflows. Please refer to the source code for details.

  • Network
    • I/O: The Turms server is a reactive application. All network I/O operations (e.g. database call, Redis call, service discovery call, RPC) are based on Netty to achieve non-blocking I/O. Therefore, the Turms server can make full use of system resources (while traditional servers can't)
    • Encoding: Protobuf is used to encode the traffic data between Turms servers and turms clients; Custom encoding without any redundant data is used to encode the RPC requests and responses between Turms servers to ensure extreme efficiency
  • Thread
    • The Turms server has an excellent thread model, and its thread number is constant, which is independent of the number of online users and the number of requests. Since the default number of threads in the access layer of the Turms server is the same as that of the CPU processors, the Turms server can make full use of the CPU cache, and greatly reduce the cost of thread context switching compared with traditional servers
    • During business logic processing, there is no synchronization or lock, only CAS
  • Memory
    • The Turms server allocates heap or direct memory smartly according to its usage to reduce the memory footprint
    • The Turms server refactors parts of MongoDB/Redis client dependencies to ensure that there is no redundant memory allocation in the Turms server, which greatly improves the effective use of memory
  • Cache: The Turms server makes full use of the local memory cache

Subprojects

Name Summary
turms-gateway A gateway (push server) interacting with clients, and responsible for user authentication, session management, push notification, and load balancing for turms-service servers
turms-service Implements IM business logic, and provides admins with business data management, RBAC, cluster management
turms-admin Provides features such as business data management and cluster management for Turms server cluster
turms-client-js Exposes APIs to interact with the Turms server to implement IM features and underlying driver logic (such as heartbeat). You don't need to know its implementations because it's transparent for developers
turns-client-kotlin ditto
turns-client-swift ditto
turms-plugin When events (such as user going online/offline, message receiving and forwarding, etc) are fired, turms-gateway and turms-service will trigger corresponding custom plugins to facilitate developers to implement custom features
turms-plugin-antispam A plugin based on turms-plugin for the anti-spam protection using Aho-Corasick automaton with double array trie (The time complexity of detection is O(n), and n is the length of target string code points)
turms-plugin-minio A plugin based on turms-plugin for the storage service, and is used to interact with MinIO server
turms-data (TODO) Not yet published. An independent data analysis system based on Flink ecosystem is responsible for business data analysis, and provides underlying data support for the statistics APIs of turms for admins and operational reports of turms-admin

Reference Architecture

The architecture design of Turms is derived from commercial instant messaging architectures. The following figure shows the reference architecture of Turms. The services framed by dotted lines are optional services, while the services framed by solid lines are required services. Please refer to Turms Architecture Design for details.

Product Comparison

Rocket.Chat Closed source IM cloud Turms
Application scenarios Team communications General IM scenarios General medium to large scale IM scenarios (Making Turms possible for redevelopment)
(Note: The first version of Turms does not provide support for living/chat room)
Advantages 1. Provide cloud services by just clicking the mouse to start the cluster and provide services
2. The client implementation is cross-platform and out-of-the-box for users
3. Support a complete and unified UI suite
4. Support rich advanced instant messaging features, such as audio and video conference, file sharing, screen sharing
5. Provide commercial users with technical support
1. Provide cloud services by just clicking the mouse to start the cluster and provide services
2. The client implementation is cross-platform and out-of-the-box for users
3. Support a complete and unified UI suite
4. Support rich advanced instant messaging features, such as audio and video conference, file sharing, screen sharing
5. Provide commercial users with technical support
The advantages are the features described above
Disadvantages 1. Only suitable for small-scale applications
2. Narrow application scenarios and hard to customize
1. It is closed source and cannot be customized. Any project will inevitably have new business requirements after business growth, which needs to be customized. However, IM clouds either do not provide customized services or require high customization fees, and they may misunderstand your requirements, resulting in customized features that cannot meet your business needs well. It will take long-term cooperation to works well with them.
But based on Turms, your requirements can be implemented and provided quickly, and the cost is low.
Note: For details of the complexity of IM, you can refer to Schema Design
2. Data Privacy. All your user information and message data are stored on IM clouds, which can peep and use your data.
Especially for some small IM companies, the data security is not guaranteed at all, and you even need to bear the risk of unrecoverable data loss.
3. The more you use IM clouds, the more you rely on it, the more expensive it is. Most IM clouds provide a certain free quota or trial period, but after the user scale of your product grows, you need to pay a high usage fee or give up the use to start develop your own IM server
4. Technical support is not timely. IM clouds need to provide technical support to a lot of customers at the same time, and the support for your product may lag behind
1. Only meets the general instant messaging needs, and does not provide some advanced features (for example, no support for audio and video conferencing)
2. The first version of Turms does not support living/chat room
3. Turms server only provides raw data of metrics/logs, and does not provide functions such as analysis and alarms
4. The web-based system administration turms-admin does not provide advanced operation features currently
5. No support for specific business logic and UI
6. Servers are reactive, which is challenging for some developers
Comment It is highly recommended to use Rocket.Chat for team communications If the IM business scenarios in your product is very common, and there is no custom requirements, and the IM business is not the main business of your product, it is recommended to use IM clouds.
But if there is no special requirements, try not to use the IM cloud provided by small companies, otherwise your data security will not be guaranteed
Although both are open source IM projects, they have completely different application scenarios. Turms is a general instant messaging engine for medium to large scale instant messaging applications. You cannot just hand Turms to your customers (just as most products don't let customers write SQL statements to query business data in the database).
However, based on Turms, you can implement all the open-source instant messaging projects on GitHub more efficiently, comprehensively, and extensively

Demo with Specific Business Implementation

Considering the positioning of Turms, we do not plan to provide client demo with UI and specific business logic in the near future because:

  • It is easy for developers to verify the business features supported by Turms. If you just want to test the business features of Turms, you can run the Turms server without even typing a line of code. Only ten lines of code can realize the login, sending messages, sending friends' requests and other business features, or modify properties to customize various requirements.
  • The design and implementation of the demo are closely related to the specific business scenarios, specific programming language, specific technical architecture, and specific OS while Turms has been committed to efficiently meeting various complex and challenging instant messaging scenarios, and we don't want to publish a demo that limits the imagination of developers. And developing and maintaining a demo is also very time-consuming and will slow down the progress of the development of Turms.
Comments
  • How to import `turms-client-kotlin` for Android projects in Gradle

    How to import `turms-client-kotlin` for Android projects in Gradle

    I tried to package turms-client-kotlin into a jar package for use in android, but the jar content after packaging became like this. I don't know what's going on?

    opened by zhangyc 17
  • client login

    client login

    关于客户端登录,应该怎么正确的理解呢? await client.userService.login(Int64(1), password: '123'); 一般应用都有自己的认证体系,客户端通过自己的认证就OK了,通过IM管理端API,换取IM认证需要的TOKEN或SESSION之类的认证凭证,给客户端?应该不再需要,再通过IM去做一次认证了? 认证的方式本身就很多种,不一定是需要输入密码的哈,感觉turms不需要管认证的方式和过程,只管鉴权就好了

    opened by itmagus 13
  • ERROR: Source emitted more than one item.  AND:  Add the batch

    ERROR: Source emitted more than one item. AND: Add the batch "AddGroupMember" function.

    I need to add a lot of member when create the gourp, Currently only one user can be added the group at a time, so i need repeat excute "AddGroupMember" api, but the service response error:

    {"code":1200,"reason":"Source emitted more than one item","timestamp":"2022-08-25T09:13:56.870+00:00"}

    I had also tried every request with a 10 second interval, it is still have this error, I don't know why this error occurs.

    Is it possible to consider adding the batch "AddGroupMember" function ?

    opened by zhjphp 10
  • storageService.uploadMessageAttachment(messageId, mediaType, data)

    storageService.uploadMessageAttachment(messageId, mediaType, data)

    请问下storageService.uploadMessageAttachment(messageId, mediaType, data) 与 sendMessage(bool isGroupMessage, Int64 targetId, {DateTime? deliveryDate, String? text, List? records, int? burnAfter, Int64? preMessageId}) 应该怎么配合使用,是先调用sendMessage,获取messageId后再调用uploadMessageAttachment?

    opened by itmagus 9
  • turms-admin install plugin Exception

    turms-admin install plugin Exception

    https://github.com/turms-im/turms/issues/1060 通过插件Debug步骤(基于IntelliJ IDEA)的方式启动正常

    通过turms-admin加载(基于“通过HTTP加载”实现):在/cluster/plugin页面,管理员也能通过UI的方式上传Java插件与JavaScript插件,的方式异常 caused by: java.lang.ClassNotFoundException: im.turms.server.common.infra.plugin.TurmsPlugin

    at java.net.URLClassLoader.findClass(unknown)
    
    at java.lang.ClassLoader.loadClass(unknown)
    
    at java.lang.ClassLoader.loadClass(unknown)
    
    at im.turms.server.common.infra.plugin.PluginClassLoader.loadClass(PluginClassLoader.java:43)
    
    at java.lang.ClassLoader.defineClass1(native)
    
    at java.lang.ClassLoader.defineClass(unknown)
    
    at java.security.SecureClassLoader.defineClass(unknown)
    
    at java.net.URLClassLoader.defineClass(unknown)
    
    at java.net.URLClassLoader$1.run(unknown)
    
    at java.net.URLClassLoader$1.run(unknown)
    
    at java.security.AccessController.doPrivileged(unknown)
    
    at java.net.URLClassLoader.findClass(unknown)
    
    at java.lang.ClassLoader.loadClass(unknown)
    
    at java.lang.ClassLoader.loadClass(unknown)
    
    at im.turms.server.common.infra.plugin.PluginClassLoader.loadClass(PluginClassLoader.java:43)
    
    at im.turms.server.common.infra.plugin.JavaPluginFactory.create(JavaPluginFactory.java:41)
    
    at im.turms.server.common.infra.plugin.PluginManager.loadJavaPlugins(PluginManager.java:191)
    
    at im.turms.server.common.domain.plugin.access.admin.controller.PluginController.createJavaPlugins(PluginController.java:126)
    
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(native)
    
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(unknown)
    
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(unknown)
    
    at java.lang.reflect.Method.invoke(unknown)
    
    at im.turms.server.common.access.admin.web.HttpRequestDispatcher.invokeHandler(HttpRequestDispatcher.java:307)
    
    at im.turms.server.common.access.admin.web.HttpRequestDispatcher.lambda$handleRequest$9(HttpRequestDispatcher.java:275)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:125)
    
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249)
    
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151)
    
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74)
    
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249)
    
    at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:101)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
    
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
    
    at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.request(FluxDefaultIfEmpty.java:77)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:238)
    
    at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onSubscribe(FluxDefaultIfEmpty.java:91)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
    
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55)
    
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
    
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
    
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55)
    
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
    
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
    
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
    
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194)
    
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2068)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
    
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55)
    
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
    
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292)
    
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187)
    
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
    
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)
    
    at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:129)
    
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)
    
    at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onComplete(MonoFlatMapMany.java:260)
    
    at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onComplete(FluxDoFinally.java:128)
    
    at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerComplete(FluxConcatMapNoPrefetch.java:286)
    
    at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onComplete(FluxConcatMap.java:887)
    
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:392)
    
    at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:527)
    
    at reactor.core.publisher.MonoRunnable.subscribe(MonoRunnable.java:50)
    
    at reactor.core.publisher.Mono.subscribe(Mono.java:4455)
    
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:384)
    
    at reactor.core.publisher.FluxIterable$IterableSubscription.fastPath(FluxIterable.java:362)
    
    at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:227)
    
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.request(FluxUsingWhen.java:319)
    
    at reactor.core.publisher.Operators$DeferredSubscription.set(Operators.java:1717)
    
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onSubscribe(FluxUsingWhen.java:409)
    
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165)
    
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87)
    
    at reactor.core.publisher.Flux.subscribe(Flux.java:8522)
    
    at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onNext(FluxUsingWhen.java:195)
    
    at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:113)
    
    at reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:251)
    
    at im.turms.server.common.infra.tracing.TracingContext.lambda$static$0(TracingContext.java:63)
    
    at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
    
    at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
    
    at java.util.concurrent.FutureTask.run(unknown)
    
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(unknown)
    
    at java.util.concurrent.ThreadPoolExecutor.runWorker(unknown)
    
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(unknown)
    
    at java.lang.Thread.run(unknown)
    
    opened by itmagus 9
  • turms-plugin-minio

    turms-plugin-minio

    按文档在本地跑,还是通过admin上传插件都报 Failed to load the plugin class im.turms.plugin.impl.MinioStorageServiceProvider image

    是因为是im.turms.的包名通过getParent().loadClass(name)应该是加载不到的? 请问turms-plugin-minio要怎么部署?

    opened by itmagus 8
  • deliveryDateAfter

    deliveryDateAfter

    client.messageService .queryMessagesWithTotal、queryMessages在传deliveryDateAfter时总会读最后一条消息,是否正常? deliveryDateAfter在判断的时候是大于等于传过去的时间? 导致的问题是,在本地同步数据的时候,需要去判断和处理。 deliveryDateBefore是正常的,deliveryDateBefore是小于传过去的时间

    opened by itmagus 8
  • How to query group history messages?

    How to query group history messages?

    Application scenarios:

    1. The new user join group, check the history messages.
    2. user check offline group message.

    I use js-client: [client.messageService.queryMessages] The server response : 1001, NO_CONTENT, I don't know where is the problem.

    And I can't find the configuration noted in the documentation: [History message] messagePersistent, recordsPersistent, messageStatusPersistent, messageTimeToLiveHours, expiredMessagesCheckerCron

    opened by zhjphp 8
  • queryMessagesWithTotal

    queryMessagesWithTotal

    https://github.com/turms-im/turms/issues/1020 queryMessagesWithTotal 的API,是否适合会话列表 https://github.com/turms-im/turms/issues/1039 turms.service.message.use-conversation-id=true. turmsClient.messageService.queryMessages({areGroupMessages: false, fromIds: [10,11,12]}), for example. 1.目前queryMessagesWithTotal和queryMessages,在不传fromIds的时候,都只能查询到对方发送的消息 2.目前queryMessagesWithTotal在传了fromIds的情况下,最后一条消息可以是自己发送的消息 3.这样的话,事先拉取,联系人和群组列表,是否就可以实现会话列表和最后一条消息的显示呢? 4.如果是这样的话,queryMessagesWithTotal为什么在开启turms.service.message.use-conversation-id=true后,一定要传fromIds呢,才能达到查询自己发送的消息呢?queryMessages的应该场景传fromIds是应该的,进入会话后才需要消费数据

    opened by itmagus 7
  • Error creating bean with name 'adminApiRateLimitingManager'

    Error creating bean with name 'adminApiRateLimitingManager'

    turms-service 在本地启动报错,启动不了 main s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminApiRateLimitingManager' defined in file [D:\workspace\code\turms\turms-service\target\classes\im\turms\service\access\admin\throttle\AdminApiRateLimitingManager.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [im.turms.service.access.admin.throttle.AdminApiRateLimitingManager]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'node' defined in class path resource [im/turms/server/common/infra/cluster/ClusterConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [im.turms.server.common.infra.cluster.node.Node]: Factory method 'node' threw exception; nested exception is java.lang.IllegalStateException: Failed to create the collection for the class: im.turms.server.common.infra.cluster.service.config.entity.property.SharedClusterProperties 启动环境dev public SharedConfigService(TurmsMongoProperties properties) { try { mongoClient = TurmsMongoClient.of(properties) .block(Duration.ofMinutes(1)); } catch (Exception e) { throw new IllegalStateException("Failed to create the shared config service", e); } List<Class<?>> classes = List.of(SharedClusterProperties.class, Leader.class, Member.class); mongoClient.registerEntitiesByClasses(classes); for (Class<?> entityClass : classes) { try { mongoClient.createCollection(entityClass).block(Duration.ofMinutes(1)); } catch (Exception e) { throw new IllegalStateException("Failed to create the collection for the class: " + entityClass.getName(), e); } } try { mongoClient.ensureIndexesAndShard(classes).block(Duration.ofMinutes(1)); } catch (Exception e) { throw new IllegalStateException("Failed to ensure the indexes are created for the classes: " + classes.stream() .map(Class::getName).toList(), e); } } image 感觉是重复创建引起的问题 image 这两个地方不抛异常的话,可以正常启动,麻烦帮看下是什么问题哈

    opened by itmagus 6
  • multi device simultaneous login, send message not as expected

    multi device simultaneous login, send message not as expected

    I fork turms and modified turms demo as follows: https://github.com/chinamcafee/turms/tree/develop/turms-client-js/demo

    I added demo2.html and js/business2.js

    About business2.js, I set login deviceType as "DESKTOP" at line 42: client.userService.login(userId, password,"DESKTOP")

    Then I opened two client page, and click "发送消息给用户1" button as follows: image

    demo2.html page shows that both user1 and user2 which login as "DESKTOP" are received message.

    But user1 at demo.html which login as default "BROWSER" didn't receive any message.

    I think User1 and User2 which login as "DESKTOP" are received message is correct, but User1 login as "BROWSER" didn't receive message is not as expected.

    Is there any bugs in my modified business2.js? Or is there some bug at server side ?

    Any help is appreciated,thanks.

    opened by chinamcafee 6
Owner
null
Facsimile - Copy Your Most Used Text to Clipboard Easily with Facsimile!. It Helps You to Store You Most Used Text as a Key, Value Pair and Copy it to Clipboard with a Shortcut.

Facsimile An exact copy of Your Information ! Report Bug · Request Feature Table of Contents About The Project Built With Getting Started Installation

Sri lakshmi kanthan P 1 Sep 12, 2022
Deploy this 🔥🔥🔥 BLAZING FAST 🔥🔥🔥 API to get instant access to ✨✨✨ INNOVATIVE ✨✨✨ API to quickly define whether the numbers are odd or even.

Is Odd API This ?? is ?? ?? a ?? simple API that ?? returns ?? whether ?? ?? a ?? number ?? ?? is ?? ?? odd ?? or ?? not. ♂ With ?? ?? this ?? ?? API

rferee 5 Sep 23, 2022
Drools is a rule engine, DMN engine and complex event processing (CEP) engine for Java.

An open source rule engine, DMN engine and complex event processing (CEP) engine for Java™ and the JVM Platform. Drools is a business rule management

KIE (Drools, OptaPlanner and jBPM) 4.9k Dec 31, 2022
图书管理;图书管理系统;图书管理系统后端,该项目采用Springboot整合Mybatis对数据持久化以及Api的封装实现,前台项目地址:https://github.com/Nirunfeng/BookSys-Client

System of Book Management(sbm) 项目说明 图书管理系统后台,该项目采用Springboot整合Mybatis对数据持久化以及Api的封装实现,前台项目地址:BookSys-Client 项目启动 数据库:mysql5.6执行以下脚本,项目下脚本文件--sbm.sql 导

null 61 Dec 30, 2022
Concurrent Programming - 2021/2022 - Fall - LI51D - LI51N

s2122i-li51d-li51n Concurrent Programming - 2021/2022 - Fall - LI51D - LI51N See docs for documentation resources. See jvm for JVM-based code examples

null 16 Apr 8, 2022
Rivr is a lightweight open-source dialogue engine enabling Java developers to easily create enterprise-grade VoiceXML applications.

Overview Rivr is a lightweight open-source dialogue engine enabling Java developers to easily create enterprise-grade VoiceXML applications. Read our

Nu Echo Inc. 57 Jun 27, 2022
A lightweight messaging library that simplifies the development and usage of RabbitMQ with the AMQP protocol.

kryo-messaging This library contains a simple MessagingService which simplifies the setup and work with RabbitMQ and the AMQP protocol. Usage Gradle r

Kryonite Labs 3 Jan 10, 2022
Framework for automated integration tests with focus on messaging integration

Citrus Integration Testing Welcome to Citrus Citrus is a test framework written in Java that is able to create fully automated end-to-end use case tes

Citrus Framework 373 Dec 27, 2022
This project is a simple messaging application made using React-Native framework, Gifted-Chat library and Firebase database

This project is a simple messaging application made using React-Native framework, Gifted-Chat library and Firebase database. The example that will be shown here focuses on the ability of two people to message each other in a chat room.

null 3 Jan 30, 2022
OwlGram is an unofficial messaging app that uses Telegram's API.

?? OwlGram OwlGram is an unofficial messaging app that uses Telegram's API. ?? About Reproducible Builds To reproduce the build of OwlGram is only nee

OwlGram Dev 193 Dec 31, 2022
MessageEngine by afkvido. Alpha test is the most updated but may contain many bugs

MessageEngine Alpha Alpha Testing This is the most frequently updated, fresh, and potentially most glitchy version of MessageEngine. This version will

gemsvidø 3 Feb 7, 2022
The most reliable world manager you've ever seen.

Rift2 - The Opening Electric Boogaloo The most reliable world manager you've ever seen. Contributors & creators: Cyberpwn Vatuu Psycho If you want to

Volmit Software 9 Dec 2, 2022
🐀 Simple, Fast and easy to implement ORM for most popular databases

RatORM Simple, Fast and easy to implement ORM for most popular databases Status: Branch Tests Code Quality master Usefull links Helpful links: GitHub

Szczurowsky 3 Dec 25, 2022
Harvest your animals in the most cursed way possible.

Reaping Harvest your animals in the most cursed way possible. By using the Reaper you can harvest food from animals as if you had killed them, but wit

Jam Core 4 Oct 23, 2022
For Jack language. Most of codes were commented with their usage, which can be useful for beginner to realize the running principle of a compiler for object-oriented programming language.

Instructions: Download the Java source codes Store these codes into a local folder and open this folder Click the right key of mouse and click ‘Open i

gooooooood 1.1k Jan 5, 2023
Esse repositório disponibiliza uma versão zero de uma API de cadastro de usuários (Users) a ser melhorada com desafios ☕️ 🇧🇷

java-training-api Esse repositório disponibiliza uma versão zero de uma API de cadastro de usuários (Users) na pasta SRC a ser melhorada. DESAFIOS Os

Guillaume Falourd 91 Dec 22, 2022
Geoponics is an E-Commerce Android Based Application Designed for Farmers As Well As Normal Users to Buy and Sell Agricultural goods!

Geoponics : E-Commerce Application Geoponics is an E-Commerce Android Based Aplication Designed for Farmers As Well As Normal Users to Buy and Sell Ag

Prasad 3 Aug 31, 2021
An Auction website. Users can Put up items for sale, bid on currently active auctions and write reviews for items that they have won in the auctions.

Auction-Project An Auction website. Users can Put up items for sale, bid on currently active auctions and write reviews for items that they have won i

Nika Salia 3 Sep 7, 2021
A compact and highly efficient workflow and Business Process Management (BPM) platform for developers, system admins and business users.

Flowable (V6) Maven Central: Docker Images: License: Homepage: https://www.flowable.org/ flowable / flowəb(ə)l / a compact and highly efficient workfl

Flowable 6k Jan 7, 2023