Skip to content

Commit 5994700

Browse files
Integrated latest changes at 05-16-2024 4:30:20 PM
1 parent b9375ae commit 5994700

File tree

4 files changed

+266
-10
lines changed

4 files changed

+266
-10
lines changed

ej2-react-toc.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@
859859
<li><a href="/ej2-react/document-editor/server-deployment/word-processor-server-docker-image-overview">Word Processor Server Docker Image Overview</a></li>
860860
<li><a href="/ej2-react/document-editor/server-deployment/how-to-deploy-word-processor-server-docker-container-in-azure-app-service">How to Deploy Word Processor Server Docker Container in Azure App Service</a></li>
861861
<li><a href="/ej2-react/document-editor/server-deployment/how-to-deploy-word-processor-server-docker-container-in-azure-kubernetes-service">How to Deploy Word Processor Server Docker Container in Azure Kubernetes Service</a></li>
862+
<li><a href="/ej2-react/document-editor/server-deployment/how-to-deploy-word-processor-server-docker-container-in-amazon-kubernetes-service">How to Deploy Word Processor Server Docker Container in Amazon Kubernetes Service</a></li>
862863
<li><a href="/ej2-react/document-editor/server-deployment/how-to-publish-documenteditor-web-api-application-in-azure-app-service-from-visual-studio">How to Publish DocumentEditor Web API Application in Azure App Service from Visual Studio</a></li>
863864
</ul>
864865
</li>

ej2-react/document-editor/collaborative-editing-java.md

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Allows multiple users to work on the same document simultaneously. This can be d
1616

1717
The following are needed to enable collaborative editing in Document Editor.
1818

19-
- Socket JS
19+
- Sock JS
2020
- PostgreSQL database
2121

2222
## How to enable collaborative editing in client side
@@ -57,9 +57,9 @@ render() {
5757
}
5858
```
5959
60-
### Step 2: Configure SocketJS to send and receive changes
60+
### Step 2: Configure SockJS to send and receive changes
6161
62-
To broadcast the changes made and receive changes from remote users, configure SocketJS like below.
62+
To broadcast the changes made and receive changes from remote users, configure SockJS like below.
6363
6464
```typescript
6565
import * as SockJS from 'sockjs-client';
@@ -98,7 +98,7 @@ public onDataRecived(data: any) {
9898
9999
### Step 3: Subscribe to specific topic while opening the document
100100
101-
When opening a document, we need to generate a unique ID for each document. These unique IDs are then used to create rooms using SocketJS, which facilitates sending and receiving data from the server.
101+
When opening a document, we need to generate a unique ID for each document. These unique IDs are then used to create rooms using SockJS, which facilitates sending and receiving data from the server.
102102
103103
```typescript
104104
public openDocument(responseText: string, roomName: string): void {
@@ -142,9 +142,9 @@ this.container.contentChange = (args: ContainerContentChangeEventArgs) => {
142142
143143
## How to enable collaborative editing in Java
144144
145-
### Step 1: Configure SocketJS hub to create room for collaborative editing session.
145+
### Step 1: Configure SockJS hub to create room for collaborative editing session.
146146
147-
To manage groups for each document, create a folder named “Hub” and add a file named ``` DocumentEditorHub.java ``` inside it. Add the following code to the file to manage SocketJS groups using room names.
147+
To manage groups for each document, create a folder named “Hub” and add a file named ``` DocumentEditorHub.java ``` inside it. Add the following code to the file to manage SockJS groups using room names.
148148
149149
Join the group by using unique id of the document by using JoinGroup method.
150150
@@ -177,7 +177,7 @@ public static void broadcastToRoom(String roomName, Object payload, MessageHeade
177177
}
178178
}
179179
```
180-
### Step 2: Handle user disconnection using SocketJS.
180+
### Step 2: Handle user disconnection using SockJS.
181181
182182
```java
183183
@EventListener
@@ -267,7 +267,7 @@ private ActionInfo addOperationsToTable(ActionInfo action) {
267267
```
268268
269269
#### Add Web API to get previous operation as a backup to get lost operations
270-
On the client side, messages send from server using SocketJS may be received in a different order, or some operations may be missed due to network issues. In these cases, we need a backup method to retrieve missing records from the database.
270+
On the client side, messages send from server using SockJS may be received in a different order, or some operations may be missed due to network issues. In these cases, we need a backup method to retrieve missing records from the database.
271271
Using the following method, we can retrieve all operations after the last successful client-synced version and return all missing operations to the requesting client.
272272
273273
```java
@@ -297,7 +297,73 @@ int clientVersion = action.getVersion();
297297
return acion;
298298
}
299299
```
300+
## How to perform Scaling in Collaborative Editing.
300301
302+
### Role of Scaling in Collaborative editing
303+
As the number of users increases, collaborative application face challenges in maintaining responsiveness and performance. This is where scaling becomes crucial. Scaling refers to the ability of an application to handle growing demands by effectively distributing the workload across multiple resources.
304+
305+
During scaling the users may connected to different servers, so collaborative editing application introduces a specific challenge like, updating the edit operations to all the users connected in different serves. To overcome this issue you need to use ``` Redis Cache pub/sub ``` for message relay(syncing the editing operations to the users connected to different server instance)
306+
307+
### Use of Redis Pub/Sub in scaling environment
308+
Redis offers Pub/Sub functionality. The publish/subscribe (pub/sub) pattern provides asynchronous communication among multiple AWS services without creating interdependency. When a user edits a document, the application can publish the changes to a Redis channel. Clients (in different server instances) subscribed to that channel receive real-time updates, reflecting the changes in their document views.
309+
310+
### Steps to configure Redis in Collaborative Editing Application
311+
Refer to the below steps to know about the Redis pub/sub implementation to sync the messages.
312+
313+
#### Step 1: Configure Redis in application level to establish the connection.
314+
315+
```java
316+
//Redis configuration
317+
spring.datasource.redishost= "<Redis host link>"
318+
spring.datasource.redisport= "<Redis port number>"
319+
```
320+
#### Step 2: Publish each editing operation to a Redis channel
321+
322+
Publish each editing operation to Redis channel with the room name. This will send notifications to all the users(in different servers) subscribed to that specific channel. Refer to the publishToRedis() method in DocumentEditorHub.Java for details.
323+
324+
```java
325+
try (Jedis jedis = RedisSubscriber.jedisPool.getResource()) {
326+
jedis.publish("collaborativeedtiting", new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(payload));
327+
break;
328+
} catch (JedisConnectionException e) {
329+
}
330+
```
331+
#### Step 3: Subscribe to the specific channel using the Redis Cache 'Subscribe'
332+
333+
Redis cache will be initialized and subscribe to the specific channel using the Redis Cache 'Subscribe' option. This ensures that users in any server will get notified when an editing operation is published to the Redis cache using the onMessage() API. Refer to the code snippet in RedisSubscriber.Java for details.
334+
335+
```java
336+
@PostConstruct
337+
public void subscribeToInstanceChannel() {
338+
//Subscriber to `collaborativeediting`
339+
String channel = "collaborativeedtiting";
340+
new Thread(() -> {
341+
JedisPoolConfig poolConfig = new JedisPoolConfig();
342+
jedisPool = new JedisPool(poolConfig, REDIS_HOST, REDIS_PORT);
343+
try (Jedis jedis = jedisPool.getResource()) {
344+
jedis.subscribe(new JedisPubSub() {
345+
@Override
346+
public void onMessage(String channel, String message) {
347+
-------------
348+
------
349+
// Message will be broadcasted to all the users connected to that room using sockjs
350+
DocumentEditorHub.broadcastToRoom(action.getRoomName(), action, updateActionheaders);
351+
} catch (JsonProcessingException e) {
352+
e.printStackTrace();
353+
}
354+
}
355+
@Override
356+
public void onSubscribe(String channel, int subscribedChannels) {
357+
System.out.println("Subscribed to channel: " + channel);
358+
}
359+
}, channel);
360+
} catch (JedisConnectionException e) {
361+
// Handle the connection exception
362+
System.out.println("Connection failed. Retrying ...");
363+
}
364+
}).start();
365+
}
366+
```
301367
302368
Full version of the code discussed about can be found in below GitHub location.
303369

ej2-react/document-editor/collaborative-editing.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ private ActionInfo AddOperationsToTable(ActionInfo action)
356356
357357
#### Add Web API to get previous operation as a backup to get lost operations
358358
359-
On the client side, messages broadcasted using SignalR may be received in a different order, or some operations may be missed due to network issues. In these cases, we need a backup method to retrieve missing records from the database.
359+
On the client side, messages broadcast using SignalR may be received in a different order, or some operations may be missed due to network issues. In these cases, we need a backup method to retrieve missing records from the database.
360360
Using the following method, we can retrieve all operations after the last successful client-synced version and return all missing operations to the requesting client.
361361
362362
```csharp
@@ -399,7 +399,46 @@ private ActionInfo AddOperationsToTable(ActionInfo action)
399399

400400
```
401401
402+
## How to perform Scaling in Collaborative Editing.
403+
404+
As the number of user increases, maintaining responsiveness and performance becomes challenging. Scaling tackles this by distributing the workload across resources. You can scale the collaborative editing application using either ```Azure SignalR service or Redis backplane service```
405+
406+
### 1. Scaling with Azure SignalR
407+
408+
Azure SignalR Service is a scalable, managed service for real-time communication in web applications. It enables real-time messaging between web clients (browsers) and your server-side application(across multiple servers).
409+
410+
Below is a code snippet to configure Azure SignalR in an ASP.NET Core application using the ```AddAzureSignalR``` method
411+
412+
```csharp
413+
builder.Services.AddSignalR() .AddAzureSignalR("<your-connection-string>", options => {
414+
// Specify the channel name
415+
options.Channels.Add("document-editor");
416+
});
417+
```
418+
419+
### 2. Scaling with Redis backplane
420+
421+
Using a Redis backplane, you achieve horizontal scaling of your SignalR application. The SignalR leverages Redis to efficiently broadcast messages across multiple servers. This allows your application to handle large user bases with minimal latency.
422+
423+
In the SignalR app, install the following NuGet package:
424+
* ` Microsoft.AspNetCore.SignalR.StackExchangeRedis`
425+
426+
Below is a code snippet to configure Redis backplane in an ASP.NET Core application using the ```AddStackExchangeRedis ``` method
427+
428+
```csharp
429+
builder.Services.AddSignalR().AddStackExchangeRedis("<your_Redis_connection_string>");
430+
```
431+
Configure options as needed:
432+
433+
The following example shows how to add a channel prefix in the ConfigurationOptions object.
434+
435+
```csharp
436+
builder.Services.AddDistributedMemoryCache().AddSignalR().AddStackExchangeRedis(connectionString, options =>
437+
{
438+
options.Configuration.ChannelPrefix = "document-editor";
439+
});
440+
```
402441
403442
Full version of the code discussed about can be found in below GitHub location.
404443
405-
Github Example: [`Collaborative editing examples`](https://github.com/SyncfusionExamples/EJ2-Document-Editor-Collaborative-Editing)
444+
GitHub Example: [`Collaborative editing examples`](https://github.com/SyncfusionExamples/EJ2-Document-Editor-Collaborative-Editing)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
---
2+
layout: post
3+
title: Deploy Syncfusion Word Processor in Amazon Kubernetes Service
4+
description: Learn here all about How to deploy word processor server docker container in amazon kubernetes service in Syncfusion React Document editor.
5+
control: How to deploy word processor server docker container in amazon kubernetes service
6+
platform: ej2-react
7+
documentation: ug
8+
domainurl: ##DomainURL##
9+
---
10+
# How to deploy Word Processor server in Amazon Kubernetes Service
11+
12+
## Prerequisites
13+
14+
* `AWS Account` :Have Amazon account
15+
* `AWS CLI`: Install the AWS Command Line Interface (CLI) on your local machine.
16+
* `Kubectl` : Install the Kubernetes command-line tool kubectl on your local machine.
17+
* `Docker`: Install Docker on your local machine.
18+
* `Word Processor Docker Image`: Have a Docker image of the Word Processor server ready to deploy.
19+
20+
To deploy the Word Processor server docker image, need to follow the below process
21+
22+
* Push Docker Image to Registry (Amazon Elastic Registry)
23+
* Deploy Docker Image on Amazon Kubernetes Service
24+
25+
Lets us discuss briefly about the each process
26+
27+
## Push the Docker image to the Amazon Elastic Registry
28+
29+
**Step 1:** Dockerize the Word Processor Server Application with the image name [syncfusion/word-processor-server](https://hub.docker.com/r/syncfusion/word-processor-server)
30+
31+
```
32+
docker build -t <your-image-name>
33+
```
34+
35+
**Step 2:** Create a private repository name ‘documenteditor’ in Amazon Elastic Container Registry (ECR) using the AWS CLI or AWS Console to push the docker image
36+
37+
```
38+
aws ecr create-repository --repository-name <repository-name>
39+
```
40+
41+
**Step 3:** Tag the image to push to ECR
42+
43+
```
44+
docker tag <your-image-name>:latest <your_ECR_registry_URI>/<your_repository_name>:latest
45+
```
46+
Refer to the following example to tag the image
47+
48+
```
49+
docker tag syncfusion/word-processor-server:latest 123456.dkr.ecr.us-east-1.amazonaws.com/documenteditor:latest
50+
```
51+
52+
> Get the ECR registry URI from AWS console or using the below AWS CLI command
53+
54+
```
55+
aws ecr describe-repositories --repository-names <repository-name> --query 'repositories[*].repositoryUri' --output text
56+
```
57+
58+
**Step 4:** Login to the ECR registry using the AWS CLI to push the docker image
59+
60+
```
61+
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <your_ECR_registry_URI>
62+
```
63+
64+
Replace <region> with your AWS region and <your_ECR_registry_URI> with your ECR registry URI.
65+
66+
**Step 5:** Push the tagged image to ECR
67+
68+
```
69+
docker push <your_ECR_registry_URI>/<your_image_name>:latest
70+
```
71+
72+
## Deploy Docker Image on Amazon Kubernetes Service
73+
74+
Follow the below steps to deploy the Docker image from the Amazon Elastic Registry( ECR) to Amazon Kubernetes Services (EKS)
75+
76+
**Step 1:** DCreate Amazon EKS cluster using the AWS Console
77+
78+
**Step 2:** Authenticate with AWS ECR
79+
Need to get the authenticate with the AWS ECR to pull the image from the registry
80+
81+
```
82+
aws ecr get-login-password --region <your-region> | docker login --username AWS --password-stdin <your-aws-account-id>.dkr.ecr.<your-region>.amazonaws.com
83+
```
84+
85+
**Step 3:** : Configure Kubernetes to Communicate with the Cluster
86+
87+
```
88+
aws eks --region <region> update-kubeconfig --name <cluster-name>
89+
```
90+
91+
**Step 4:** Tag the Docker Image to the created cluster
92+
93+
```
94+
docker tag <your-aws-account-id>.dkr.ecr.<your-region>.amazonaws.com/<repository-name>:<tag> <your-eks-cluster-id>.dkr.ecr.<your-region>.amazonaws.com/<repository-name>:<tag>
95+
```
96+
97+
Refer to the following example
98+
```
99+
docker tag 12345.dkr.ecr.us-east-1.amazonaws.com/documenteditor:latest 98765ABCD.dkr.ecr.us-east-1.amazonaws.com/documenteditor:latest
100+
```
101+
102+
In this command:
103+
* <your-eks-cluster-id> should be replaced with your EKS cluster ID, which is the base part of your EKS cluster endpoint (e.g., abcd1234).
104+
* <your-region> should be replaced with your AWS region.
105+
106+
107+
**Step 5:** To create Kubernetes deployment write Kubernetes manifest
108+
109+
**i.** Create a Kubernetes Deployment manifest (deployment.yaml) for your application. Specify the Docker image location.
110+
111+
```
112+
apiVersion: apps/v1
113+
kind: Deployment
114+
metadata:
115+
name: ```your-deployment```
116+
spec:
117+
replicas: 3
118+
selector:
119+
matchLabels:
120+
app: ```your-app```
121+
template:
122+
metadata:
123+
labels:
124+
app: ```your-app```
125+
spec:
126+
containers:
127+
- name: your-container
128+
image: ```<account-id>.dkr.ecr.<region>.amazonaws.com/your-repository-name:tag```
129+
ports:
130+
- containerPort: 80
131+
```
132+
**ii.** Apply the Deployment manifest to create the deployment in your EKS cluster
133+
134+
```
135+
kubectl apply -f deployment.yaml
136+
```
137+
138+
**iii.** Use port forwarding to access the Word Processor Server application locally and verify its functionality
139+
140+
```
141+
kubectl port-forward pod-name local-port:container-port
142+
```
143+
144+
> Get the pod names in AWS Console or using the below AWS CLI command
145+
146+
```
147+
kubectl get pods
148+
```
149+
150+
Finally you can get the sample in the localhost http://```<your-ip>```/api/documenteditor/

0 commit comments

Comments
 (0)