diff --git a/turms-docs/src/.vitepress/config.ts b/turms-docs/src/.vitepress/config.ts index e4531b4f63..2bb0fc1a2d 100644 --- a/turms-docs/src/.vitepress/config.ts +++ b/turms-docs/src/.vitepress/config.ts @@ -95,8 +95,8 @@ export default defineConfig({ text: 'Development', items: [ { - text: 'About Secondary Development', - link: '/server/development/redevelopment.md' + text: 'About Custom Development', + link: '/server/development/customization.md' }, { text: 'Basic Development Rules', @@ -313,8 +313,8 @@ export default defineConfig({ text: '开发', items: [ { - text: '关于二次开发', - link: '/zh-CN/server/development/redevelopment.md' + text: '关于定制化开发', + link: '/zh-CN/server/development/customization.md' }, { text: '基本开发规约', diff --git a/turms-docs/src/client/turms-chat-demo.md b/turms-docs/src/client/turms-chat-demo.md index d4932b5187..546c0d8e51 100644 --- a/turms-docs/src/client/turms-chat-demo.md +++ b/turms-docs/src/client/turms-chat-demo.md @@ -4,12 +4,12 @@ Initially, our plan was to let users to reuse existing XMPP clients by making turms-gateway support the XMPP protocol. However, both paid and free XMPP clients have generally low quality, mainly due to the following reasons: -1. Most XMPP client projects have poor code quality, especially early client engineers who lack coding skills. They often mix complex UI logic with business logic (e.g., the famous open-source project JMeter), making it difficult for redevelopment. It is better to rewrite them from scratch. +1. Most XMPP client projects have poor code quality, especially early client engineers who lack coding skills. They often mix complex UI logic with business logic (e.g., the famous open-source project JMeter), making it difficult for customization. It is better to rewrite them from scratch. 2. Both commercial and open-source XMPP clients have UI designs that are at an amateur level. If a client project lacks a professional UI, we doubt the capabilities of their frontend engineers and UI designers (a competent intermediate frontend engineer should be capable of designing a single product UI independently). We do not recommend users to adopt their solutions. 3. There is hardly any open-source XMPP client that supports a complete cross-platform solution. 4. Many low-quality XMPP clients even require payment. -Considering that developing a cross-platform IM application is not difficult and mainly involves manual work, and that IM application UI and functionalities are highly generic (researching 10 commercial IM applications in the market would reveal that at least 9 of them have similar UI and functionalities), we decided to first provide the IM client demo `turms-chat-demo-flutter` for Turms users to use or redevelopment. We will support the XMPP protocol later. +Considering that developing a cross-platform IM application is not difficult and mainly involves manual work, and that IM application UI and functionalities are highly generic (researching 10 commercial IM applications in the market would reveal that at least 9 of them have similar UI and functionalities), we decided to first provide the IM client demo `turms-chat-demo-flutter` for Turms users to use or customize. We will support the XMPP protocol later. ## Roadmap @@ -30,13 +30,13 @@ We want to emphasize the term `demo` in the project name. This term mainly has t 1. Whether from a product perspective or a technical perspective, this client "demo" is just one of the "possible" solutions. Users should not limit their ability to design their own IM products because of this "demo." Especially, do not assume that Turms' server is customized for this "demo." As repeatedly mentioned in the Turms documentation, Turms is a generic IM solution dedicated to solving various IM scenarios. 2. Prepare for users' further development. This mainly involves three aspects: - 1. Separation of UI and business logic. This allows teams that need to do redevelopment to reuse the UI to implement their own business logic. Readers can even use the `turms-chat-demo-flutter` project without the Turms server, but instead use their own self-developed IM server. + 1. Separation of UI and business logic. This allows teams that need to customize to reuse the UI to implement their own business logic. Readers can even use the `turms-chat-demo-flutter` project without the Turms server, but instead use their own self-developed IM server. 2. We continue to use the permissive Apache 2.0 license instead of the more restrictive GPL license commonly used in client open-source projects. - 3. Since the UI design of IM applications worldwide is very similar, this `demo` will also implement most of the generic UI and logic for IM. It generally does not provide more customized logic to facilitate redevelopment by other teams. + 3. Since the UI design of IM applications worldwide is very similar, this `demo` will also implement most of the generic UI and logic for IM. It generally does not provide more customized logic to facilitate customization by other teams. Note: `demo` does not imply "low quality." Readers will understand this by examining the code quality and UI design later. -## Redevelopment +## Custom Development Due to the numerous design patterns for Flutter applications, many applications lack a unified design, resulting in multiple conflicting designs within a single application, making the architecture look very chaotic. diff --git a/turms-docs/src/community/index.md b/turms-docs/src/community/index.md index 12bd765a65..5734bf1b74 100644 --- a/turms-docs/src/community/index.md +++ b/turms-docs/src/community/index.md @@ -90,15 +90,15 @@ For Turms, upstream first mainly involves two aspects: communication and code fe Note: Because of the complexity of requirements, many "seemingly" issues on GitHub Issues are in "pending". Many feature-related issues are just seeds that developers need to do more detailed requirement analysis, design, and coding, and the most difficult thing is usually requirement analysis, which needs to clarify "what needs to be done", and developers need to consider both current and future requirements, and prevent over-design. This is also why Turms documentation mentions several times that "the design and implementation of IM business functions are far more difficult than the design and implementation of technology middleware". -* Reduce your maintenance costs and facilitate the continuous merging of upstream updates. If a developer forks the Turms project for complex secondary development, they will face a long-term maintenance problem: if the developer wants to use upstream's new code, they need to constantly adapt their own branch, and the faster upstream Turms server updates, the greater the developer's adaptation workload. There may even be logical conflicts that the developer is not aware of. +* Reduce your maintenance costs and facilitate the continuous merging of upstream updates. If a developer forks the Turms project for complex custom development, they will face a long-term maintenance problem: if the developer wants to use upstream's new code, they need to constantly adapt their own branch, and the faster upstream Turms server updates, the greater the developer's adaptation workload. There may even be logical conflicts that the developer is not aware of. On the contrary, if developers give back the code to upstream, such problems will not occur. Because we will not only maintain these feedbacked codes together, but also consider whether these new designs and these feedbacked codes are consistent in design when designing other new related functional modules for Turms. -* Reduce maintenance conflicts and avoid overturning local implementations repeatedly. Developers may have added some new features or fixed some bugs locally, but have not given back. After a period of time, developers may find that upstream considers the functionality they have implemented to be more thoughtful and complete, and the bug fixes are more ingenious (readers can read about the difficulty of Turms server-side bugs in [Task Difficulty](https://turms-im.github.io/docs/server/development/redevelopment#%E6%9C%8D%E5%8A%A1%E7%AB%AF)). Ultimately, developers have to revert all their original work, then re-pull upstream and start over again. The workload among them is painful to think about, and the more developers change locally, the more conflicts there may be. +* Reduce maintenance conflicts and avoid overturning local implementations repeatedly. Developers may have added some new features or fixed some bugs locally, but have not given back. After a period of time, developers may find that upstream considers the functionality they have implemented to be more thoughtful and complete, and the bug fixes are more ingenious (readers can read about the difficulty of Turms server-side bugs in [Task Difficulty](https://turms-im.github.io/docs/server/development/customization#%E6%9C%8D%E5%8A%A1%E7%AB%AF)). Ultimately, developers have to revert all their original work, then re-pull upstream and start over again. The workload among them is painful to think about, and the more developers change locally, the more conflicts there may be. ### About Contacting Turms Author for Private Chat and Custom Development -If readers' teams are interested in doing redevelopment themselves, they can directly refer to the article on [Redevelopment](https://turms-im.github.io/docs/en-US/server/development/redevelopment.html). +If readers' teams are interested in doing custom development, they can directly refer to the article on [Custom Development](https://turms-im.github.io/docs/en-US/server/development/customization.html). For users who wish to pay Turms' author for custom development, it's worth noting that Turms' author generally only accepts unpaid development for common needs (yes, generally, only unpaid development for the community). The reason for this is quite simple; Turms' author doesn't lack money, and even if the Turms project incurs a loss of several tens of thousands of Chinese yuan every year, we can still ensure the continuous operation of the Turms project because we never intended to profit from it in the first place. So, either we will only accept a very high offer that's hard to refuse, or we will only accept unpaid development for the community. diff --git a/turms-docs/src/design/status-aware.md b/turms-docs/src/design/status-aware.md index 5fec6691d8..42bf6c85b5 100644 --- a/turms-docs/src/design/status-aware.md +++ b/turms-docs/src/design/status-aware.md @@ -208,13 +208,13 @@ Turms will also support the above-mentioned session-level message auto-increment #### plan -| | Does not support offline message push with unread message count (default implementation) | supports offline message push with unread message count (TODO) | -| --------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| Implementation | When the client receives and pulls messages, it sends a request to the server to calculate the "unread messages" in real time.
In this solution, the Turms server does not actually have the concept of `unread message count`, the server only calculates the number of messages within a certain message sending time interval according to the client's request | Use Redis to support offline messages Carry the number of unread messages when pushing: carry the number of unread messages in the session and the total number of unread messages; only carry the total number of unread messages Add 1 to the number of unread messages, and add 1 to the total
When the user reads the message, or when the user or group is deleted, do the opposite subtraction operation in the Redis record
(**Note: The total number of unread messages must be calculated by the server **) | -| Advantages | 1. The implementation is simple and can flexibly support various business needs, without the need to introduce a Redis server
2. When sending a message, there is no need to send a request to Redis to calculate the number of unread messages, and the write throughput is higher | 1. Support offline message push to carry the number of unread messages
2. When reading unread messages, no real-time calculation is required, and the read throughput is higher | -| Disadvantages | 1. Does not support the number of unread messages carried when offline messages are pushed
2. When the client reads the number of unread messages, real-time calculation is required, and the read throughput is lower (supplement: index support) | 1 . Redis server needs to be introduced to increase the cost and difficulty of operation and maintenance
2. Every time the server receives a new message, Redis needs to send a request to calculate the number of unread messages, and the write throughput is lower | -| Relationship with unread messages | `Unread messages` and `Number of unread messages` both take the terminal as the dimension, and the client sends the local message to the service through the above-mentioned client to confirm the last confirmation time to obtain this time point The number of "unread" messages and "unread" messages after that.
Therefore, the `unread message` and `unread message number` obtained by different terminals may be inconsistent | `unread message` still takes the terminal as the dimension, but `unread message number` takes the user as the dimension . If message A is "read" on the desktop side, the mobile phone side can still consider it "unread", but the number of unread messages pushed to all clients of the user is uniformly reduced by 1
So the different ends get `Unread Messages` may be inconsistent, but `Unread Message Count` is consistent | -| Supplement | As mentioned above, this solution can actually "forcibly" support the number of unread messages when pushing offline messages.
But because this solution is not designed for frequently reading the number of unread messages, if the server calculates the number of unread messages in real time every time a message is pushed, its performance is obviously not advisable. Therefore, it is not supported in practice | The above solutions have their own advantages and disadvantages, and which solution to use depends on the business requirements of the specific application. If you do not need to support offline message push and carry the number of unread messages, use the solution on the left, and if you need to support it, use the solution on the right.
If the customer has additional requirements on the basis of these two solutions, they need to do secondary development by themselves
TODO: This implementation will be supported in the near future | +| | Does not support offline message push with unread message count (default implementation) | supports offline message push with unread message count (TODO) | +| --------------------------------- | ------------------------------------------------------------ |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Implementation | When the client receives and pulls messages, it sends a request to the server to calculate the "unread messages" in real time.
In this solution, the Turms server does not actually have the concept of `unread message count`, the server only calculates the number of messages within a certain message sending time interval according to the client's request | Use Redis to support offline messages Carry the number of unread messages when pushing: carry the number of unread messages in the session and the total number of unread messages; only carry the total number of unread messages Add 1 to the number of unread messages, and add 1 to the total
When the user reads the message, or when the user or group is deleted, do the opposite subtraction operation in the Redis record
(**Note: The total number of unread messages must be calculated by the server **) | +| Advantages | 1. The implementation is simple and can flexibly support various business needs, without the need to introduce a Redis server
2. When sending a message, there is no need to send a request to Redis to calculate the number of unread messages, and the write throughput is higher | 1. Support offline message push to carry the number of unread messages
2. When reading unread messages, no real-time calculation is required, and the read throughput is higher | +| Disadvantages | 1. Does not support the number of unread messages carried when offline messages are pushed
2. When the client reads the number of unread messages, real-time calculation is required, and the read throughput is lower (supplement: index support) | 1 . Redis server needs to be introduced to increase the cost and difficulty of operation and maintenance
2. Every time the server receives a new message, Redis needs to send a request to calculate the number of unread messages, and the write throughput is lower | +| Relationship with unread messages | `Unread messages` and `Number of unread messages` both take the terminal as the dimension, and the client sends the local message to the service through the above-mentioned client to confirm the last confirmation time to obtain this time point The number of "unread" messages and "unread" messages after that.
Therefore, the `unread message` and `unread message number` obtained by different terminals may be inconsistent | `unread message` still takes the terminal as the dimension, but `unread message number` takes the user as the dimension . If message A is "read" on the desktop side, the mobile phone side can still consider it "unread", but the number of unread messages pushed to all clients of the user is uniformly reduced by 1
So the different ends get `Unread Messages` may be inconsistent, but `Unread Message Count` is consistent | +| Supplement | As mentioned above, this solution can actually "forcibly" support the number of unread messages when pushing offline messages.
But because this solution is not designed for frequently reading the number of unread messages, if the server calculates the number of unread messages in real time every time a message is pushed, its performance is obviously not advisable. Therefore, it is not supported in practice | The above solutions have their own advantages and disadvantages, and which solution to use depends on the business requirements of the specific application. If you do not need to support offline message push and carry the number of unread messages, use the solution on the left, and if you need to support it, use the solution on the right.
If the customer has additional requirements on the basis of these two solutions, they need to do custom development
TODO: This implementation will be supported in the near future | #### Implementation diff --git a/turms-docs/src/index.md b/turms-docs/src/index.md index b86d3f6fda..9e54eba64b 100644 --- a/turms-docs/src/index.md +++ b/turms-docs/src/index.md @@ -127,12 +127,12 @@ The architecture design of Turms is derived from commercial instant messaging ar Although there are many open source IM projects in the world, there is only one open source IM project designed for medium and large IM application scenarios: Turms. -| | [Rocket.Chat](https://github.com/RocketChat/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 | +| | [Rocket.Chat](https://github.com/RocketChat/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 custom development)
(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](https://turms-im.github.io/docs/design/schema#%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E4%B8%8E%E9%9B%86%E5%90%88%E7%BB%93%E6%9E%84%E8%AE%BE%E8%AE%A1)
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 | +| 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 diff --git a/turms-docs/src/server/development/redevelopment.md b/turms-docs/src/server/development/customization.md similarity index 60% rename from turms-docs/src/server/development/redevelopment.md rename to turms-docs/src/server/development/customization.md index 241fcd95ba..36a9479611 100644 --- a/turms-docs/src/server/development/redevelopment.md +++ b/turms-docs/src/server/development/customization.md @@ -1,6 +1,6 @@ -# About Secondary Development +# About Custom Development -## Reasons for Secondary Development Based on Turms +## Reasons for Custom Development Based on Turms ### Objective Reasons @@ -8,7 +8,7 @@ * Normative. Since the architecture design of Turms is a variant of the standard commercial instant messaging architecture, if your professional team is based on common commercial standards, the architecture designed by your team is similar to the current architecture of Turms, and there is no need to start from scratch. Zero self-development. -* Simplicity. The entire architecture of Turms and the implementation of each module are actually relatively simple and lightweight, and the secondary development is not difficult. +* Simplicity. The entire architecture of Turms and the implementation of each module are actually relatively simple and lightweight, and the custom development is not difficult. * Controllability. Turms is developed based on the Apache V2 protocol, 100% open source, and has self-developed many basic middleware, which ensures the controllability of the underlying technology and avoids insufficient development momentum in the later stage of the project. @@ -44,7 +44,7 @@ In addition, if you are still hesitating whether to adopt other open source IM p * The core business of your project is related to instant messaging, or you have plans to further develop instant messaging business. * The extended functions required by your project are not currently available in Turms, especially the extended functions that need to be implemented through auxiliary index tables (for auxiliary index tables, please refer to [Turms Collection Design](https://turms-im.github.io/docs/design/schema)). -* Your project has a large number of project-specific IM implementation details. Although Turms provides hundreds of configuration items, these are only general configurations. According to the specific business needs, the specific implementation of IM-related functions is extremely rich, but it is impossible for Turms to directly provide the realization of these relatively niche business functions, otherwise the amount of code will increase exponentially, so you need to do secondary development by yourself. +* Your project has a large number of project-specific IM implementation details. Although Turms provides hundreds of configuration items, these are only general configurations. According to the specific business needs, the specific implementation of IM-related functions is extremely rich, but it is impossible for Turms to directly provide the realization of these relatively niche business functions, otherwise the amount of code will increase exponentially, so you need to do custom development. ## Project Import @@ -94,9 +94,110 @@ Notes: * In the `dev` environment, turms-service will automatically generate fake data to the MongoDB database, and turms-gateway will also automatically create TCP-based fake clients, and these clients will randomly (random request type, random request parameters) send turms-gateway sends real client requests to facilitate testing by developers. * If you want to replace the port of the MongoDB server, you only need to globally replace `27017` with your target port under the Turms project. +## Custom Attributes + +Developers using Turms often request a feature: the ability to add custom attributes to models such as users, groups, and relationships. This allows for various customized business functionalities, such as: + +- Adding information like `company`, `department`, and `email` to users, with support for custom attributes that can be queried by other users. +- Allowing the current user to add custom `notes` for their contacts. +- Sharing certain attributes for chat sessions across multiple devices, such as `pinning` and `new message notifications`. + +Although Turms is designed to focus solely on core instant messaging functionalities and we do not plan to provide direct support for the aforementioned relatively customized features, developers do not need to modify Turms' source code to implement these functionalities. Instead, they can configure the turms-service server to manage the logic for adding, deleting, updating, and querying these custom attributes. + +### User-Defined Attributes of the Model + +Used to add user-defined attributes to user and group models. + +#### turms-service Related Properties + +| Property | Description | Default Value | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------- | +| turms.service.user.info.user-defined-attributes | Used to define user-defined attributes for the `User` model | | +| turms.service.user.info.user-defined-attributes.ignore-unknown-attributes-on-upsert | Whether to ignore unknown attributes (i.e., attributes not declared in `turms.service.user.info.user-defined-attributes.allowed-attributes`) when upserting user-defined attributes on the turms-service server. If set to `false`, an error will be returned when a user attempts to insert an unknown attribute; if set to `true`, the turms-service will ignore the unknown user-defined attribute, will not return an error, and will continue processing other known user-defined attributes. | false | +| turms.service.user.info.user-defined-attributes.allowed-attributes | Specifies a set of user-defined attributes that the client is allowed to use. Note: This attribute is an array. | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].source-name | Specifies which key (field name) from the client's request in `userDefinedAttributes` to retrieve the user-defined attribute value. | "" | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].stored-name | Specifies the field name to store the client request data in the database. If not specified, the source-name will be used as the field name. | "" | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].immutable | Whether the value is immutable. If set to `true`, the user will not be able to modify the stored value. | false | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.type | The type of the value. Possible types include: * INT: corresponds to MongoDB's `int` * LONG: corresponds to MongoDB's `long` * DOUBLE: corresponds to MongoDB's `double` * BOOL: corresponds to MongoDB's `bool` * STRING: corresponds to MongoDB's `string` * LANGUAGE: corresponds to MongoDB's `string` * ARRAY: corresponds to MongoDB's `array` | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.int-value.min | When the value type is `INT`, specifies the allowed minimum value (inclusive of min value). | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.int-value.max | When the value type is `INT`, specifies the allowed maximum value (inclusive of max value). | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.long-value.min | When the value type is `LONG`, specifies the allowed minimum value (inclusive of min value). | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.long-value.max | When the value type is `LONG`, specifies the allowed maximum value (inclusive of max value). | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.double-value.min | When the value type is `DOUBLE`, specifies the allowed minimum value (inclusive of min value). | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.double-value.max | When the value type is `DOUBLE`, specifies the allowed maximum value (inclusive of max value). | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.string-value.min-length | When the value type is `STRING`, specifies the allowed minimum string length (inclusive of min-length value). | 0 | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.string-value.max-length | When the value type is `STRING`, specifies the allowed maximum string length (inclusive of max-length value). | 100 | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.string-value.regexes[?] | When the value type is `STRING`, specifies the regular expressions used to validate the input string value. | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.min-element-count | When the value type is `ARRAY`, specifies the allowed minimum array length (inclusive of min-element-count value). | 0 | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.max-element-count | When the value type is `ARRAY`, specifies the allowed maximum array length (inclusive of max-element-count value). | 10 | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.unique | When the value type is `ARRAY`, whether to deduplicate the values in the array. | false | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.allow-null-element | When the value type is `ARRAY`, whether to allow `null` values in the array. | false | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.element | When the value type is `ARRAY`, specifies the type of elements in the array. | | +| turms.service.user.info.group-defined-attributes.allowed-attributes | Used to define user-defined attributes for the `Group` model. Since the usage of this attribute is identical to that of `turms.service.user.info.user-defined-attributes`, it will not be elaborated further. | | + +**Note**: The Turms server currently only supports public user-defined attributes. In other words, any user has permission to query the user-defined attributes of all users and groups. + +#### Client-Related Interfaces + +* Update User User-defined Attributes Interface: `turmsClient.userService.updateProfile` +* Update Group User-defined Attributes Interface: `turmsClient.groupService.updateGroup` + +For specific interface logic details, please refer to the interface documentation in the client SDK source code. + +### Custom Settings + +Some developer users wish for Turms to store custom user and session settings, such as user settings: `Client Language`, `UI Theme`, etc., and session settings: `Pin`, `New Message Notifications`, `Notes`, etc. + +#### turms-service Service Related Properties + +| Property | Description | Default Value | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------- | +| turms.service.user.settings | Used for custom user settings | | +| turms.service.user.settings.ignore-unknown-settings-on-upsert | Whether to ignore unknown settings (i.e., settings not declared in `turms.service.user.settings.allowed-settings`) when upserting custom settings on the turms-service server. If set to `false`, an error will be returned when a user attempts to insert an unknown setting; if set to `true`, the turms-service will ignore the unknown custom setting, will not return an error, and will continue processing other known custom settings. | false | +| turms.service.user.settings.ignore-unknown-settings-on-delete | Whether to ignore unknown settings (i.e., settings not declared in `turms.service.user.settings.allowed-settings`) when deleting custom settings on the turms-service server. If set to `false`, an error will be returned when a user attempts to delete an unknown setting; if set to `true`, the turms-service will ignore the unknown custom setting, will not return an error, and will continue processing other known custom settings. | | +| turms.service.user.settings.allowed-settings | Specifies a set of custom settings that the client is allowed to use.
Note: This attribute is an array. | | +| turms.service.user.settings.allowed-settings[?].source-name | Specifies which key (field name) from the client's request in `settings` to retrieve the custom setting value. | "" | +| turms.service.user.settings.allowed-settings[?].stored-name | Specifies the field name to store the client request data in the database. If not specified, the source-name will be used as the field name. | "" | +| turms.service.user.settings.allowed-settings[?].immutable | Whether the value is immutable. If set to `true`, the user will not be able to modify the stored value. | false | +| turms.service.user.settings.allowed-settings[?].deletable | Whether the value can be deleted. If set to `true`, the user can delete the stored value. | true | +| turms.service.user.settings.allowed-settings[?].value | See the above `turms.service.user.info.user-defined-attributes.allowed-attributes[?].value`. | | +| turms.service.conversation.settings | Used for custom conversation settings.
Since the usage of this attribute is identical to that of `turms.service.user.settings`, it will not be elaborated further. | | + +#### Client-Related Interfaces + +* User Custom Settings + + * Upsert User Custom Settings Interface: `turmsClient.userService.upsertUserSettings` + * Delete User Custom Settings Interface: `turmsClient.userService.deleteUserSettings` + * Query User Custom Settings Interface: `turmsClient.userService.queryUserSettings` + +* Conversation Custom Settings + + * Upsert Conversation Custom Settings Interface: + * `turmsClient.conversationService.upsertPrivateConversationSettings` + * `turmsClient.conversationService.upsertGroupConversationSettings` + + * Delete Conversation Custom Settings Interface: `turmsClient.conversationService.deleteConversationSettings` + + * Query Conversation Custom Settings Interface: `turmsClient.conversationService.queryConversationSettings` + +For specific interface logic details, please refer to the interface documentation in the client SDK source code. + +## Request and Response Model + +To facilitate developers in easily, quickly, and efficiently customizing Turms, we have added the `repeated Value custom_attributes = 15` field to the Protobuf transmission model for both the Turms client and server. Developers can flexibly use these fields according to their specific business scenarios on both the client and server sides. + +The Turms system, including all Turms clients and servers, will not use these fields itself. + +Note: In the source code and interfaces of the Turms system, we have made distinctions in the names of various custom attributes to clarify their meanings: + +* **Custom Attributes**: Specifically refers to custom attributes in the Protobuf model. +* **User Defined Attributes**: Specifically refers to custom attributes in the storage model (corresponding to MongoDB's Collection). +* **Properties**: Specifically refers to properties of the Turms server. + ## About Task Difficulty -For teams that are planning to do secondary development based on Turms (change the source code of the Turms project itself), you can refer to the task difficulty table below to assign tasks to members. +For teams that are planning to do custom development based on Turms (change the source code of the Turms project itself), you can refer to the task difficulty table below to assign tasks to members. The difficulty value of the task ranges from 0 to 10, where: diff --git a/turms-docs/src/server/development/testing.md b/turms-docs/src/server/development/testing.md index 3c4d20862f..89c1991447 100644 --- a/turms-docs/src/server/development/testing.md +++ b/turms-docs/src/server/development/testing.md @@ -34,4 +34,4 @@ In the final analysis, laymen watch the excitement, and experts watch the way. N Although Turms does not plan to provide a ready-made stress test report, we will customize a distributed stress test platform for the Turms server in the near future. The platform's UI display and report analysis will be in charge of turms-admin, while node control and task execution will be in charge of the Controller node and Agent node in turms-performance-testing respectively. -In particular, the reason why Turms can quickly customize and develop many platforms also benefits from our [reasons for secondary development based on Turms](https://turms-im.github.io/docs/server/development/redevelopment#%E5%9F%BA%E4%BA%8Eturms%E5%81%9A%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E7%9A%84%E5%8E%9F%E5%9B%A0) mentioned "controllability. The Turms project is 100% open source and has self-developed many basic middleware to ensure the controllability of the underlying technology. It avoids insufficient development motivation in the later stage of the project", so we will not be subject to third-party dependence when we do new projects, and we are full of motivation. \ No newline at end of file +In particular, the reason why Turms can quickly customize and develop many platforms also benefits from our [reasons for custom development based on Turms](https://turms-im.github.io/docs/server/development/customization#%E5%9F%BA%E4%BA%8Eturms%E5%81%9A%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E7%9A%84%E5%8E%9F%E5%9B%A0) mentioned "controllability. The Turms project is 100% open source and has self-developed many basic middleware to ensure the controllability of the underlying technology. It avoids insufficient development motivation in the later stage of the project", so we will not be subject to third-party dependence when we do new projects, and we are full of motivation. \ No newline at end of file diff --git a/turms-docs/src/zh-CN/client/turms-chat-demo.md b/turms-docs/src/zh-CN/client/turms-chat-demo.md index 68b2e641f4..c6d052fefa 100644 --- a/turms-docs/src/zh-CN/client/turms-chat-demo.md +++ b/turms-docs/src/zh-CN/client/turms-chat-demo.md @@ -4,12 +4,12 @@ 最初,我们是计划先通过让turms-gateway支持XMPP协议来让用户能够自行复用世界上已有的XMPP客户端。但是不管是收费,还是免费的XMPP客户端质量基本都不高,主要体现在: -1. 大多XMPP客户端项目代码质量差,尤其是很多早期客户端工程师的代码功底很差,甚至会把复杂的UI逻辑与业务逻辑杂糅在一起写(比如著名开源项目JMeter),二次开发不如自己重写。 +1. 大多XMPP客户端项目代码质量差,尤其是很多早期客户端工程师的代码功底很差,甚至会把复杂的UI逻辑与业务逻辑杂糅在一起写(比如著名开源项目JMeter),定制化开发不如自己重写。 2. 不管是商业还是开源的UI设计水平基本都停留在业余爱好者水平。如果一个客户端项目没有专业的UI,我们会对其团队的前端工程师与UI设计师的能力表示怀疑(团队中只要有一位靠谱的、中级水平的前端工程师,就应该有独立设计单一产品UI的能力),也不会推荐用户去用他们的方案。 3. 几乎没有一个开源的XMPP客户端支持完整的跨平台方案。 4. 很多质量不高的XMPP客户端甚至需要收费。 -考虑到提供一套跨桌面端与移动端IM应用的开发难度不高,主要是体力活,并且IM应用的UI与功能通用性强(在市面上找10款IM商业应用调研,会发现至少有9款IM的UI与功能是基本类似的),因此决定先提供IM客户端Demo`turms-chat-demo-flutter`,让Turms的用户能够自己使用或二次开发,之后再支持XMPP协议。 +考虑到提供一套跨桌面端与移动端IM应用的开发难度不高,主要是体力活,并且IM应用的UI与功能通用性强(在市面上找10款IM商业应用调研,会发现至少有9款IM的UI与功能是基本类似的),因此决定先提供IM客户端Demo`turms-chat-demo-flutter`,让Turms的用户能够自己使用或定制化开发,之后再支持XMPP协议。 ## RoadMap @@ -29,14 +29,14 @@ 我们想着重提醒项目名中的一词——`demo`。该词主要有以下几种含义: 1. 不管是从产品角度,还是技术角度,该客户端`demo`也只不过是其中`可能的`的方案之一,用户不应该因为该`demo`而限制设计自身IM产品的能力,尤其不要认为Turms的服务端是为该`demo`定制的,正如Turms文档中反复提及Turms是一个通用IM解决方案,致力于解决各种IM场景。 -2. 为用户的二次开发做准备。这主要分为三个方面: - 1. UI与业务逻辑分离。方便需要二次开发的团队复用UI来实现自己的业务逻辑,读者甚至可以只用`turms-chat-demo-flutter`项目,不使用Turms服务端,而是使用自研的IM服务端。 +2. 为用户的定制化开发做准备。这主要分为三个方面: + 1. UI与业务逻辑分离。方便需要定制化开发的团队复用UI来实现自己的业务逻辑,读者甚至可以只用`turms-chat-demo-flutter`项目,不使用Turms服务端,而是使用自研的IM服务端。 2. 依旧采用宽松的Apache 2.0,而不是客户端开源项目常见的、更加严格的GPL协议。 - 3. 由于全球范围的IM应用的UI设计都非常类似,因此该`demo`也会实现大部分IM的通用UI与逻辑,一般不提供更为定制化的逻辑,以方面其他团队二次开发。 + 3. 由于全球范围的IM应用的UI设计都非常类似,因此该`demo`也会实现大部分IM的通用UI与逻辑,一般不提供更为定制化的逻辑,以方面其他团队定制化开发。 注意:`demo`没有`质量低`的含义,这点读者之后看代码质量与UI设计就可明白。 -## 关于二次开发 +## 关于定制化开发 由于Flutter应用的设计模式众多,很多应用缺乏统一的设计,导致一个应用中存在众多互斥的设计,架构看起来非常混乱。 diff --git a/turms-docs/src/zh-CN/community/index.md b/turms-docs/src/zh-CN/community/index.md index 9e2b3af064..95b4d08b71 100644 --- a/turms-docs/src/zh-CN/community/index.md +++ b/turms-docs/src/zh-CN/community/index.md @@ -92,15 +92,15 @@ ChatGPT是一个优秀的背诵者,但它对各种技术方案的分析都很 额外补充:正是因为需求的复杂性,所以Turms很多“看起来”的Issues是处于“悬而未决”的状态。Turms GitHub Issues区中,有大量Open Issues,很多特性相关的Issues只是一个种子,需要开发者自行做更细致的需求分析、设计与编码,而其中最难的通常就是需求分析,需要弄清楚“到底要做什么”,开发者既要考虑现在的需求,也得考虑未来的需求,还得防止过度设计,这也是为什么Turms文档中好几次提到类似“IM业务功能的设计与实现其实远比技术中间件的设计与实现难得多的多”。 -* 降低自己的维护成本,方便持续性地合并上游更新。如果开发者Fork Turms项目做复杂的二次开发,那将面临一个长期维护的问题:如果开发者想要使用上游的新代码,就需要不断地在自己的分支上做适配,而上游Turms服务端更新得越快,开发者的适配工作量就越大。甚至还有可能出现逻辑上的冲突,但开发者没意识到。 +* 降低自己的维护成本,方便持续性地合并上游更新。如果开发者Fork Turms项目做复杂的定制化开发,那将面临一个长期维护的问题:如果开发者想要使用上游的新代码,就需要不断地在自己的分支上做适配,而上游Turms服务端更新得越快,开发者的适配工作量就越大。甚至还有可能出现逻辑上的冲突,但开发者没意识到。 相反的,如果开发者将代码回馈给上游,那就不会出现这类问题。因为我们不仅会一起来维护这些被回馈的代码,而且在为Turms设计其他新的相关功能模块时,也会考虑这些新设计与这些被回馈的代码在设计上是否一致。 -* 减少维护冲突,避免反复推翻本地实现。可能开发者自己在本地添加了一些新特性或者修复了一些Bugs,但都没有回馈。过一段时间之后,开发者可能会发现上游比自己实现的功能考虑得更周全且完善,一些Bugs的修复更精妙(关于Turms服务端Bugs的难度介绍,读者可以阅读[关于任务难度](https://turms-im.github.io/docs/zh-CN/server/development/redevelopment#%E6%9C%8D%E5%8A%A1%E7%AB%AF),最终开发者不得不把自己原来做的工作全Revert,然后再重新拉去上游搭配,重头做一遍适配。这其中的工作量想想就令人感觉痛苦,开发者在本地改得越多,冲突也就可能越多。 +* 减少维护冲突,避免反复推翻本地实现。可能开发者自己在本地添加了一些新特性或者修复了一些Bugs,但都没有回馈。过一段时间之后,开发者可能会发现上游比自己实现的功能考虑得更周全且完善,一些Bugs的修复更精妙(关于Turms服务端Bugs的难度介绍,读者可以阅读[关于任务难度](https://turms-im.github.io/docs/zh-CN/server/development/customization#%E6%9C%8D%E5%8A%A1%E7%AB%AF),最终开发者不得不把自己原来做的工作全Revert,然后再重新拉去上游搭配,重头做一遍适配。这其中的工作量想想就令人感觉痛苦,开发者在本地改得越多,冲突也就可能越多。 ### 关于想找Turms作者私聊与做定制化开发 -如果读者的团队是想自己做二次开发,可以直接看文章[关于二次开发](https://turms-im.github.io/docs/zh-CN/server/development/redevelopment.html)。 +如果读者的团队是想自己做定制化开发,可以直接看文章[关于定制化开发](https://turms-im.github.io/docs/zh-CN/server/development/customization.html)。 如果一些用户想付费找Turms作者做定制化开发,但Turms作者一般只接受为通用需求做无偿开发(是的,一般只接受免费帮社区做开发)。其中的原因很简单,Turms作者不缺钱,即便Turms项目持续每年亏损几万人民币,我们也都能保证Turms这项目持续运营下去,因为我们从始至终压根没打算盈利。所以要么只接受用户很高的报价,高到令人难以拒绝,要么就只接受为社区做免费的开发。 diff --git a/turms-docs/src/zh-CN/design/architecture.md b/turms-docs/src/zh-CN/design/architecture.md index 0f6fb06fe5..43bbb5a0ab 100644 --- a/turms-docs/src/zh-CN/design/architecture.md +++ b/turms-docs/src/zh-CN/design/architecture.md @@ -10,7 +10,7 @@ 4. (可观测性)具备相对完善的可观测性体系设计,为业务统计与错误排查提供可能 5. (可拓展性)能同时支持中大型即时通讯场景,即便用户体量由小变大也无需重构(当然,对于大型运用场景还有很多优化的工作需要做,但当前架构不影响后期的无痛升级) 6. (安全性)提供限流防刷机制与用户/IP黑名单机制,以抵御大部分CC攻击 -7. (简单性)核心架构“轻量”,方便学习与二次开发(原因请查阅 [Turms架构设计](https://turms-im.github.io/docs/zh-CN/design/architecture)) +7. (简单性)核心架构“轻量”,方便学习与定制化开发(原因请查阅 [Turms架构设计](https://turms-im.github.io/docs/zh-CN/design/architecture)) 8. Turms使用MongoDB分片架构,以支持请求路由(如读写分离),同时也支持跨地域多活部署与数据主主同步,为大规模跨国部署提供实际操作的可能 ## 架构说明 diff --git a/turms-docs/src/zh-CN/design/schema.md b/turms-docs/src/zh-CN/design/schema.md index 97337256a8..f20153bfdc 100644 --- a/turms-docs/src/zh-CN/design/schema.md +++ b/turms-docs/src/zh-CN/design/schema.md @@ -13,7 +13,7 @@ * **集合索引主要是针对分布式数据分片的特点与约束条件,并根据多查少写、以关键的普适即时通讯需求为主要需求而设计的** * **集合索引不针对数据分析做设计**(具体请查阅 [Turms数据分析](https://turms-im.github.io/docs/zh-CN/server/module/data-analytics)) * **集合索引不针对管理员接口做设计**(避免不必要的索引开销,代价就是管理员接口的灵活性相对差) -* **Turms不采用辅助索引集合来满足拓展的业务功能**(因此如果您的项目有拓展业务功能,您就需要基于Turms进行二次开发。当然,实现起来也很简单,合格的中高级工程师都应该有这样的能力) +* **Turms不采用辅助索引集合来满足拓展的业务功能**(因此如果您的项目有拓展业务功能,您就需要基于Turms进行定制化开发。当然,实现起来也很简单,合格的中高级工程师都应该有这样的能力) 这里特别要强调的就是“**以关键的普适即时通讯需求为主**”,因为它提醒了集合的设计不仅需要开发人员注意,甚至还需要产品经理与甲方的注意。对于涉及到分布式数据分片的场景,一些看似“实现简单”的功能在实际落地时会带来大量的资源消耗并提高开发与运维的难度,因此针对这样“吃力不讨好”的功能,请务必多方确认该需求是否合理,是否必要,是否能承担相应的风险与成本。在确认是否需要实现、能否经过多次迭代后再实现等现实因素后,再考虑是否需要对集合做弹性设计,以方便后期更新,降低推翻重构的风险。 diff --git a/turms-docs/src/zh-CN/design/status-aware.md b/turms-docs/src/zh-CN/design/status-aware.md index eef0c8aec7..d30276b9c0 100644 --- a/turms-docs/src/zh-CN/design/status-aware.md +++ b/turms-docs/src/zh-CN/design/status-aware.md @@ -214,7 +214,7 @@ Turms会同时支持上述的会话级消息自增ID实现来保证消息100%必 | 优点 | 1. 实现简单且可以灵活地支持各种业务需求,无需专门引入Redis服务端
2. 发送消息时,无需向Redis发送请求去计算消息未读数,写吞吐量更高 | 1. 支持离线消息推送时携带未读消息数
2. 读取未读消息时,不需要实时计算,读吞吐量更高 | | 缺点 | 1. 不支持离线消息推送时携带未读消息数
2. 客户端读取未读消息数时,需要实时计算,读吞吐量更低(补充:有索引支持) | 1. 需要引入Redis服务端,增加运维成本与难度
2. 服务端每次接收到新消息,都需要Redis发送请求去计算消息未读数,写吞吐量更低 | | 与未读消息的关系 | `未读消息`与`未读消息数`都是以端为维度,由客户端自行通过上述的客户端向服务发送本地消息最后确认时间,来获取这个时间点之后的“未读”消息与“未读”消息数。
因此不同端得到的`未读消息`与`未读消息数`可能是不一致的 | `未读消息`仍是以端为维度,但`未读消息数`则以用户为维度。如果消息A在桌面端被“读”了,那手机端仍可以认为其“未读”,但推送给该用户所有客户端的未读消息数都统一减了1
因此不同端得到的`未读消息`可能是不一致的,但`未读消息数`是一致的 | -| 补充 | 如上文所述,该方案其实也能“强行”支持离线消息推送时携带未读消息数。
但因为这方案并不是为频繁读取未读消息数而设计的,因此如果每次推送消息时,都让服务端自行实时计算未读消息数,其性能明显是不可取的,因此实践上是不支持的 | 上述方案各有优劣,具体用哪个方案,取决于具体应用的业务需求。不需要支持离线消息推送时携带未读消息数,则采用左侧的方案,需要支持则采用右侧的方案。
如果客户在这两个方案基础上,还有额外需求,则需要自行做二次开发
TODO:该实现将在近期支持 | +| 补充 | 如上文所述,该方案其实也能“强行”支持离线消息推送时携带未读消息数。
但因为这方案并不是为频繁读取未读消息数而设计的,因此如果每次推送消息时,都让服务端自行实时计算未读消息数,其性能明显是不可取的,因此实践上是不支持的 | 上述方案各有优劣,具体用哪个方案,取决于具体应用的业务需求。不需要支持离线消息推送时携带未读消息数,则采用左侧的方案,需要支持则采用右侧的方案。
如果客户在这两个方案基础上,还有额外需求,则需要自行做定制化开发
TODO:该实现将在近期支持 | #### 具体实现 diff --git a/turms-docs/src/zh-CN/index.md b/turms-docs/src/zh-CN/index.md index 07fd8216ae..a344c32782 100644 --- a/turms-docs/src/zh-CN/index.md +++ b/turms-docs/src/zh-CN/index.md @@ -62,7 +62,7 @@ Turms基于读扩散消息模型进行架构设计,对业务数据变化感知 当您需要将Turms与其他开源IM项目做具体特性的比对时,您可以先照着Turms下述的特性与其他开源IM项目进行比对。通常情况下,您能通过这样的比对,发现专业IM项目与业余IM项目之间的区别。另外,在`产品对比`章节下,我们也提到了Turms项目的缺点供您参考。 -注意:当前Turms项目的主要缺点是不对直播/聊天室业务场景提供支持。直播/聊天室业务场景的技术实现并不难,但其产品需求、质量属性要求与约束性条件与一般的社交场景存在着较大差异,故Turms第一版设计不对其提供支持;另外,Turms也不太适用于小规模的企业通讯场景,用Turms往企业通讯场景上套就有点“杀鸡用牛刀”,因为企业通讯更强调功能丰富而非极限性能,与Turms的目标不符,所以二者的上层设计也不同。如果希望支持企业通讯场景,您还需要对Turms进行二次开发。 +注意:当前Turms项目的主要缺点是不对直播/聊天室业务场景提供支持。直播/聊天室业务场景的技术实现并不难,但其产品需求、质量属性要求与约束性条件与一般的社交场景存在着较大差异,故Turms第一版设计不对其提供支持;另外,Turms也不太适用于小规模的企业通讯场景,用Turms往企业通讯场景上套就有点“杀鸡用牛刀”,因为企业通讯更强调功能丰富而非极限性能,与Turms的目标不符,所以二者的上层设计也不同。如果希望支持企业通讯场景,您还需要对Turms进行定制化开发。 ### 业务功能相关特性 @@ -78,7 +78,7 @@ Turms基于读扩散消息模型进行架构设计,对业务数据变化感知 4. (可观测性)具备相对完善的可观测性体系设计,为业务统计与错误排查提供可能 5. (可拓展性)能同时支持中大型即时通讯场景,即便用户体量由小变大也无需重构(当然,对于大型运用场景还有很多优化的工作需要做,但当前架构不影响后期的无痛升级) 6. (安全性)提供限流防刷机制与全局用户/IP黑名单机制,以抵御大部分CC攻击 -7. (简单性)核心架构“轻量”,方便学习与二次开发(原因请查阅 [Turms架构设计](https://turms-im.github.io/docs/zh-CN/design/architecture)) +7. (简单性)核心架构“轻量”,方便学习与定制化开发(原因请查阅 [Turms架构设计](https://turms-im.github.io/docs/zh-CN/design/architecture)) 8. Turms使用MongoDB分片架构,并支持请求路由(如读写分离)、冷热数据分离,同时也支持跨地域多活部署与数据主主同步,为大规模跨国部署提供实际操作的可能 ### 其他特性 @@ -135,9 +135,9 @@ Turms的架构设计脱胎于商用即时通讯架构。下图为Turms的参考 | | [Rocket.Chat](https://github.com/RocketChat/Rocket.Chat) | 大量具有高关注度的低质IM项目 | 闭源的即时通讯云 | Turms | | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------ | -| 应用场景 | 企业内部通讯 | 企业内部通讯 | 通用的即时通讯场景 | 通用的中大规模即时通讯场景(为二次开发提供实际操作的可能)
(注:第一版设计不对直播/聊天室业务场景提供支持) | +| 应用场景 | 企业内部通讯 | 企业内部通讯 | 通用的即时通讯场景 | 通用的中大规模即时通讯场景(为定制化开发提供实际操作的可能)
(注:第一版设计不对直播/聊天室业务场景提供支持) | | 优点 | 1. 提供云服务,点点鼠标即可启动集群,并对外提供服务
2. 客户端支持众多平台且开箱即用
3. 带有完整且风格统一的UI套件
4. 具有大量的拓展即时通讯功能,包括音视频会议、文件传输、桌面共享等高级功能
5. 商业版有技术团队支持 | 1. 部分开发者具有开源奉献精神 | 1. 提供云服务,点点鼠标即可启动集群,并对外提供服务
2. 客户端支持众多平台且开箱即用
3. 带有完整且风格统一的UI套件
4. 具有大量的拓展即时通讯功能,包括音视频会议、文件传输、桌面共享等高级功能
5. 商业版有技术团队支持 | 优点即上文所述特性。
补充:外网自建,无需公安备案 | -| 缺点 | 1. 只适合小规模部署(千人以下)
2. 适用场景窄,功能可定制性差 | 1. 项目技术人员技术视野窄,代码质量过低,无软件工程思维,总体水平业余。如:系统不具备可观察性、无防刷与黑名单机制,被CC攻击时,只能停机
2. 项目大多具有玩票性质。通常维护者在长期维护过程中,会发现当前服务架构混乱不堪,但又没能力重构,或者发现同领域内还有其他开源的且对方项目具有碾压性优势的时候,热情大减,放弃继续维护项目
3. 项目大多哗众取宠,通常还伴随互刷关注度。由于吸引初级程序员更容易快速获取关注度,该类项目多会提供一些业余水平的UI界面与外强中干的产品功能,最终积重难返,彻底沦为玩具项目
4. 部分项目仅公开部分源码(如只公开客户端代码,不公开服务端代码),以假借开源名义来推广低质的收费服务。但其收费服务远不如免费的Rocket.Chat,跟融云、网易云信等成熟的商业服务相比就更无优势可言了
5. KPI项目或面试用项目。目的完成后便抛弃项目 | 1. 闭源,无法自定义实现。任何项目在业务增长之后必将出现新的业务需求,需要进行定制。但通讯云要么不提供定制服务,要么需要高昂的定制费用,且第三方平台可能会对您业务理解出现偏差,造成定制功能不能很好地满足您业务需求,二者需要长期的磨合。
而基于Turms自研就可以快速开发并快速上线,成本也低。另:即时通讯的复杂性可以参考[集合结构设计](https://turms-im.github.io/docs/zh-CN/design/schema#%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E4%B8%8E%E9%9B%86%E5%90%88%E7%BB%93%E6%9E%84%E8%AE%BE%E8%AE%A1)
2. 数据泄露。您所有的用户信息与聊天记录都存储在第三方平台,其可以偷窥和使用您的数据。
特别是一些IM小公司,数据的安全性完全没有保障,您甚至需要承受数据丢失无法恢复的风险
3. 越用越依赖,越用越贵。多数通讯云提供一定的免费额度或试用期,但在您产品的用户规模增长之后,您需要支付高昂的使用费或放弃使用开始自研
4. 技术支持不及时。通讯云需要同时对多个客户提供技术支持,对您产品的支持可能滞后
5. 需要公安备案 | 1. 只满足通用的即时通讯需求,不提供拓展功能的实现(如:不具备常用的音视频会议功能。TODO:Turms后期会基于SFU媒体服务器为Turms主服务端定制一套信令服务端,目前您可自行选择其他音视频会议解决方案与Turms进行集成)
2. Turms第一版设计不对直播/聊天室业务场景提供支持
3. 服务端只提供度量/日志等原始数据,不提供分析与报警等功能
4. 配套的Web后台管理系统`turms-admin`不提供专业的运维功能(注意:Turms配套的后台系统和商用的运维系统是相辅相成的)。
5. 不提供客户端具体的上层业务逻辑实现与UI支持
6. 服务端基于响应式编程,对二次开发者的技术水平要求相对高 | +| 缺点 | 1. 只适合小规模部署(千人以下)
2. 适用场景窄,功能可定制性差 | 1. 项目技术人员技术视野窄,代码质量过低,无软件工程思维,总体水平业余。如:系统不具备可观察性、无防刷与黑名单机制,被CC攻击时,只能停机
2. 项目大多具有玩票性质。通常维护者在长期维护过程中,会发现当前服务架构混乱不堪,但又没能力重构,或者发现同领域内还有其他开源的且对方项目具有碾压性优势的时候,热情大减,放弃继续维护项目
3. 项目大多哗众取宠,通常还伴随互刷关注度。由于吸引初级程序员更容易快速获取关注度,该类项目多会提供一些业余水平的UI界面与外强中干的产品功能,最终积重难返,彻底沦为玩具项目
4. 部分项目仅公开部分源码(如只公开客户端代码,不公开服务端代码),以假借开源名义来推广低质的收费服务。但其收费服务远不如免费的Rocket.Chat,跟融云、网易云信等成熟的商业服务相比就更无优势可言了
5. KPI项目或面试用项目。目的完成后便抛弃项目 | 1. 闭源,无法自定义实现。任何项目在业务增长之后必将出现新的业务需求,需要进行定制。但通讯云要么不提供定制服务,要么需要高昂的定制费用,且第三方平台可能会对您业务理解出现偏差,造成定制功能不能很好地满足您业务需求,二者需要长期的磨合。
而基于Turms自研就可以快速开发并快速上线,成本也低。另:即时通讯的复杂性可以参考[集合结构设计](https://turms-im.github.io/docs/zh-CN/design/schema#%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90%E4%B8%8E%E9%9B%86%E5%90%88%E7%BB%93%E6%9E%84%E8%AE%BE%E8%AE%A1)
2. 数据泄露。您所有的用户信息与聊天记录都存储在第三方平台,其可以偷窥和使用您的数据。
特别是一些IM小公司,数据的安全性完全没有保障,您甚至需要承受数据丢失无法恢复的风险
3. 越用越依赖,越用越贵。多数通讯云提供一定的免费额度或试用期,但在您产品的用户规模增长之后,您需要支付高昂的使用费或放弃使用开始自研
4. 技术支持不及时。通讯云需要同时对多个客户提供技术支持,对您产品的支持可能滞后
5. 需要公安备案 | 1. 只满足通用的即时通讯需求,不提供拓展功能的实现(如:不具备常用的音视频会议功能。TODO:Turms后期会基于SFU媒体服务器为Turms主服务端定制一套信令服务端,目前您可自行选择其他音视频会议解决方案与Turms进行集成)
2. Turms第一版设计不对直播/聊天室业务场景提供支持
3. 服务端只提供度量/日志等原始数据,不提供分析与报警等功能
4. 配套的Web后台管理系统`turms-admin`不提供专业的运维功能(注意:Turms配套的后台系统和商用的运维系统是相辅相成的)。
5. 不提供客户端具体的上层业务逻辑实现与UI支持
6. 服务端基于响应式编程,对需要定制化开发的工程师的技术水平要求相对高 | | 总评 | 几乎是开源届中企业内部通讯实现的最优开源项目,非常推荐 | 受众主要是不了解即时通讯领域的初级程序员,Rocket.Chat跟这类产品相比具有碾压性的优势 | 如果您产品所涉及的IM业务场景非常常规,没有定制化需求,且IM业务也不是您产品的主营业务,则推荐使用成熟的即时通讯云。另外,如果没有特殊原因,尽量不要使用小公司的通讯云服务,否则您的数据安全性将毫无保障 | Rocket.Chat和Turms虽然同为即时通讯领域的开源项目,但二者在应用场景上几乎没有交集。
因为Tumrs是面向通用的中大型即时通讯应用场景,且相对底层的即时通讯引擎。您无法直接将Turms引擎交给您的客户使用(就像大部分产品不会让客户直接写SQL语句来查询数据库里的业务模型一样)。
但基于Turms,您可以更高效、更全方位、更扩展地实现目前GitHub上所有开源的即时通讯项目 | ## 关于带具体业务实现的Demo diff --git a/turms-docs/src/zh-CN/server/development/redevelopment.md b/turms-docs/src/zh-CN/server/development/customization.md similarity index 93% rename from turms-docs/src/zh-CN/server/development/redevelopment.md rename to turms-docs/src/zh-CN/server/development/customization.md index 641d2dae76..0aad4a841f 100644 --- a/turms-docs/src/zh-CN/server/development/redevelopment.md +++ b/turms-docs/src/zh-CN/server/development/customization.md @@ -1,6 +1,6 @@ -# 关于二次开发 +# 关于定制化开发 -## 基于Turms做二次开发的原因 +## 基于Turms做定制化开发的原因 ### 客观原因 @@ -8,7 +8,7 @@ * 规范性。由于Turms的架构设计是标准商用即时通讯架构的变种,因此如果您的专业团队是以常见的商用标准为要求,您的团队设计出来的架构也与Turms现在的架构相差不多的,没有必要另起炉灶从零自研。 - * 简易性。Turms整个架构与各个模块的实现其实都比较简洁与轻量的,二次开发难度不高。 + * 简易性。Turms整个架构与各个模块的实现其实都比较简洁与轻量的,定制化开发难度不高。 * 可控性。Turms基于Apache V2协议进行开发,100%开源,并对很多基础中间件进行了自研,保证了底层技术的可控,避免了项目后期发展动力不足。 @@ -44,7 +44,7 @@ * 您项目的核心业务与即时通讯相关,或者有深耕于即时通讯业务的计划。 * 您项目所需要的拓展功能Turms目前暂未提供,尤其是需要通过辅助索引表来实现的拓展功能(关于辅助索引表,可查看[Turms集合设计](https://turms-im.github.io/docs/zh-CN/design/schema))。 - * 您项目存在大量项目独有的IM实现细节。Turms虽然提供了上百个配置项,但这些也只是普适的配置。根据具体业务需求的不同,IM相关功能的具体实现极其丰富,但Turms不可能直接提供这些相对小众业务功能的实现,否则代码量将会指数级增加,因此需要您自行做二次开发。 + * 您项目存在大量项目独有的IM实现细节。Turms虽然提供了上百个配置项,但这些也只是普适的配置。根据具体业务需求的不同,IM相关功能的具体实现极其丰富,但Turms不可能直接提供这些相对小众业务功能的实现,否则代码量将会指数级增加,因此需要您自行做定制化开发。 ## 项目引入 @@ -98,24 +98,24 @@ Turms服务端开发环境的搭建其实也非常简单,具体步骤包括: Turms的开发者用户经常会提出一类需求,即:希望Turms能够支持给用户、群组、关系等模型添加自定义的属性,以实现各种各样的定制化业务功能,如: -* 需要给用户加上`所属公司`、`部门`、`邮箱`等信息,并且这些信息支持用户自定义,且支持其他用户查询。 +* 需要给用户加上`所属公司`、`部门`、`邮箱`等信息,并且这些信息支持自定义,且支持其他用户查询。 * 需要实现当前用户能够给他的联系人添加自定义`备注(note)`。 * 需要在多个设备之间,共享给聊天会话的一些属性配置,如`置顶`与`新消息提醒`。 尽管在Turms的系统设计上,它只被允许实现即时通讯的核心功能,并且我们也无计划对上述相对定制化的功能提供直接支持,但实现上述功能,开发者用户其实并不需要修改Turms的源码,只需要对turms-service服务端进行配置,即可实现对这些自定义属性的增删改查逻辑。 -### 自定义模型属性 +### 模型的用户自定义属性(User-Defined Attributes) -实现给用户与群组模型添加自定义的属性。 +用于给用户与群组模型添加用户自定义属性。 #### turms-service服务相关属性 | 属性 | 作用 | 默认值 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | -| turms.service.user.info.user-defined-attributes | 用于定义`用户`模型的自定义属性 | | -| turms.service.user.info.user-defined-attributes.ignore-unknown-attributes-on-upsert | 在turms-service服务端upsert自定义属性时,是否忽略未知(即未在`turms.service.user.info.user-defined-attributes.allowed-attributes`声明的属性)。如果该值为`false`,则当用户请求插入未知属性时,响应错误;如果该值为`true`,则turms-service会忽略该自定义属性,并不会响应错误,并且继续处理其他已知自定义属性 | false | -| turms.service.user.info.user-defined-attributes.allowed-attributes | 指定一组允许客户端使用的自定义属性。
注意:该属性是一个数组 | | -| turms.service.user.info.user-defined-attributes.allowed-attributes[?].source-name | 指定从客户端请求中的`userDefinedAttributes`的哪个键(字段名)获取自定义属性值 | "" | +| turms.service.user.info.user-defined-attributes | 用于定义`用户`模型的用户自定义属性 | | +| turms.service.user.info.user-defined-attributes.ignore-unknown-attributes-on-upsert | 在turms-service服务端upsert用户自定义属性时,是否忽略未知(即未在`turms.service.user.info.user-defined-attributes.allowed-attributes`声明的属性)。如果该值为`false`,则当用户请求插入未知属性时,响应错误;如果该值为`true`,则turms-service会忽略该用户自定义属性,并不会响应错误,并且继续处理其他已知用户自定义属性 | false | +| turms.service.user.info.user-defined-attributes.allowed-attributes | 指定一组允许客户端使用的用户自定义属性。
注意:该属性是一个数组 | | +| turms.service.user.info.user-defined-attributes.allowed-attributes[?].source-name | 指定从客户端请求中的`userDefinedAttributes`的哪个键(字段名)获取用户自定义属性值 | "" | | turms.service.user.info.user-defined-attributes.allowed-attributes[?].stored-name | 指定将客户端请求数据存储在数据库时的字段名。如果未指定该值,则使用source-name作为字段名 | "" | | turms.service.user.info.user-defined-attributes.allowed-attributes[?].immutable | 是否该值不可变。如果为`true`,则用户将无法修改已经存储的值 | false | | turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.type | 值的类型。可以是下述类型:
* INT:对应MongoDB的`int`
* LONG:对应MongoDB的`long`
* DOUBLE:对应MongoDB的`double`
* BOOL:对应MongoDB的`bool`
* STRING:对应MongoDB的`string`
* LANGUAGE:对应MongoDB的`string`
* ARRAY:对应MongoDB的`array` | | @@ -133,9 +133,9 @@ Turms的开发者用户经常会提出一类需求,即:希望Turms能够支 | turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.unique | 当值类型为`ARRAY`时,是否对数组的值进行去重 | false | | turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.allow-null-element | 当值类型为`ARRAY`时,是否允许数组中包含`null`值 | false | | turms.service.user.info.user-defined-attributes.allowed-attributes[?].value.array-value.element | 当值类型为`ARRAY`时,指定数组的元素类型 | | -| turms.service.user.info.group-defined-attributes.allowed-attributes | 用于定义`群组`模型的自定义属性。
由于该属性的用法与上述的`turms.service.user.info.user-defined-attributes`的用法完全一致,故不赘述 | | +| turms.service.user.info.group-defined-attributes.allowed-attributes | 用于定义`群组`模型的用户自定义属性。
由于该属性的用法与上述的`turms.service.user.info.user-defined-attributes`的用法完全一致,故不赘述 | | -注意:Turms服务端目前只支持公开的自定义属性。换言之,任何用户都有权限查询所有用户与群组的自定义属性。 +注意:Turms服务端目前只支持公开的用户自定义属性。换言之,任何用户都有权限查询所有用户与群组的用户自定义属性。 #### 客户端相关接口 @@ -144,7 +144,7 @@ Turms的开发者用户经常会提出一类需求,即:希望Turms能够支 关于具体的接口逻辑细节,请阅读客户端SDK源码中的接口说明。 -### 自定义配置 +### 自定义配置(Custom Settings) 一些开发者用户希望Turms能够存储自定义的用户与会话配置,如用户配置:`客户端语言`、`UI主题`等,如会话配置:`置顶`、`新消息提醒`、`备注`等。 @@ -197,7 +197,7 @@ Turms系统,包括所有Turms客户端与服务端,它们自身都不会去 ## 关于任务难度 -对于准备基于Turms做二次开发(改Turms项目自身的源码)的团队,可以参考下述的任务难度表,给成员分配任务。 +对于准备基于Turms做定制化开发(改Turms项目自身的源码)的团队,可以参考下述的任务难度表,给成员分配任务。 任务的难度值为0~10,其中: diff --git a/turms-docs/src/zh-CN/server/development/testing.md b/turms-docs/src/zh-CN/server/development/testing.md index 0838d3ae65..3818b59df0 100644 --- a/turms-docs/src/zh-CN/server/development/testing.md +++ b/turms-docs/src/zh-CN/server/development/testing.md @@ -34,4 +34,4 @@ 尽管Turms没计划提供现成的压测报告,但我们近期会为Turms服务端定制一套分布式压测平台。该平台的UI展示与报告分析会由turms-admin负责,而节点管控与任务执行分别由turms-performance-testing中的Controller节点与Agent节点负责。 -特别一提的是:Turms之所以能快速定制与开发众多平台,也得益于我们在[基于Turms做二次开发的原因](https://turms-im.github.io/docs/zh-CN/server/development/redevelopment#%E5%9F%BA%E4%BA%8Eturms%E5%81%9A%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E7%9A%84%E5%8E%9F%E5%9B%A0)提到的“可控性。Turms项目100%开源,并对很多基础中间件进行了自研,保证了底层技术的可控,避免了项目后期发展动力不足”,因此我们做新项目不会受制于第三方依赖,动力十足。 \ No newline at end of file +特别一提的是:Turms之所以能快速定制与开发众多平台,也得益于我们在[基于Turms做定制化开发的原因](https://turms-im.github.io/docs/zh-CN/server/development/customization#%E5%9F%BA%E4%BA%8Eturms%E5%81%9A%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E7%9A%84%E5%8E%9F%E5%9B%A0)提到的“可控性。Turms项目100%开源,并对很多基础中间件进行了自研,保证了底层技术的可控,避免了项目后期发展动力不足”,因此我们做新项目不会受制于第三方依赖,动力十足。 \ No newline at end of file