댓글 검색 목록

[Nodejs] Chatt 구축-실시간 다중 사용자 GraphQL 채팅 앱

페이지 정보

작성자 운영자 작성일 21-04-10 15:36 조회 1,225 댓글 0

GraphQL 구독의 가장 인기 있는 사용 사례 중 하나는 실시간 통신 (예 : 메시징 앱)을 지원하는 애플리케이션을 구축하는 것입니다.


더 어려운 일 중 하나는 데이터 모델이 다소 복잡해지기 시작하고 연결된 클라이언트 수가 많을 때 확장성 문제가 발생하기 시작함에 따라 여러 사용자 및 여러 채널에서 이 실시간 기능이 작동하도록 하는 것입니다.


저는 최근에 여러 사용자가 실시간 기능을 구현하고 대화 중인지 여부에 따라 개별 채널 (채팅)을 구독 할 수 있는 기능을 구현하는 오픈 소스 앱인 Chatt을 개발 및 출시했습니다.


이와 같은 것을 만들 때 설정해야 하는 두 가지 주요 부분이 있습니다.

  1. 사용자 관리
  2. API

일반적으로 이 두 가지를 처음부터 새로 구축하는 것은 최소한의 작업이며 확장 가능하고 안전하게 구축하는 데 몇 달이 걸릴 수 있습니다.


감사하게도 오늘날 우리는 이러한 유형의 워크로드를 처리하기 위해 관리형 서비스를 가동 할 수 있는 Auth0, Firebase, Okta 및 AppSync와 같은 서비스가 있습니다.


내 앱은 GraphQL API 및 AWS Amplify용 AWS AppSync를 사용하여 사용자 관리 서비스를 생성하고 있습니다. 이 앱은 이러한 서비스와 함께 작동하도록 제작되었지만 다른 백엔드 또는 인증 공급자로 쉽게 대체 될 수 있습니다.


이 앱과 백엔드를 직접 배포하려면 README의 지침을 확인하세요.


코드 


일부 코드를 간략히 살펴 보겠습니다. 가장 먼저 살펴볼 것은 기본 스키마입니다.


type User {
  id: ID!
  username: String!
  conversations(filter: ModelConvoLinkFilterInput, sortDirection: ModelSortDirection, limit: Int, nextToken: String): ModelConvoLinkConnection
  messages(filter: ModelMessageFilterInput, sortDirection: ModelSortDirection, limit: Int, nextToken: String): ModelMessageConnection
  createdAt: String
  updatedAt: String
}

type Conversation {
  id: ID!
  messages(filter: ModelMessageFilterInput, sortDirection: ModelSortDirection, limit: Int, nextToken: String): ModelMessageConnection
  associated(filter: ModelConvoLinkFilterInput, sortDirection: ModelSortDirection, limit: Int, nextToken: String): ModelConvoLinkConnection
  name: String!
  members: [String!]!
  createdAt: String
  updatedAt: String
}

type Message {
  id: ID!
  author: User
  authorId: String
  content: String!
  conversation: Conversation!
  messageConversationId: ID!
  createdAt: String
  updatedAt: String
}

type ConvoLink {
  id: ID!
  user: User!
  convoLinkUserId: ID
  conversation: Conversation!
  convoLinkConversationId: ID!
  createdAt: String
  updatedAt: String
}


세 가지 기본 GraphQL 유형이 있습니다 : 사용자, 대화 및 메시지. 대화와 사용자 간의 연결을 제공하는 ConvoLink 유형도 있습니다.


이러한 유형에 대한 작업 및 해결 프로그램은 여기에서 자세히 볼 수 있습니다.


다음으로 살펴볼 것은 앱이 API와 상호 작용하는 방식에 대한 좋은 보기를 제공하기 때문에 클라이언트에서 사용할 GraphQL 작업 (쿼리, 구독 및 변형)입니다.


Mutations 


// This creates a new user, storing their username.
// Even though the authentication service will be handling the user management, we will also need some association with the user in the database.
const createUser = `
  mutation($username: String!) {
    createUser(input: {
      username: $username
    }) {
      id username createdAt
    }
  }
`

// This creates a new message.
// The association between the message & the conversation is made with the __messageConversationId__.
const createMessage = `mutation CreateMessage(
    $createdAt: String, $id: ID, $authorId: String, $content: String!, $messageConversationId: ID!
  ) {
  createMessage(input: {
    createdAt: $createdAt, id: $id, content: $content, messageConversationId: $messageConversationId, authorId: $authorId
  }) {
    id
    content
    authorId
    messageConversationId
    createdAt
  }
}
`;

// This creates a new conversation.
// We store the members that are involved with the conversation in the members array.
const createConvo = `mutation CreateConvo($name: String!, $members: [String!]!) {
  createConvo(input: {
    name: $name, members: $members
  }) {
    id
    name
    members
  }
}
`;

// This makes the association between the conversations & the users.
const createConvoLink = `mutation CreateConvoLink(
    $convoLinkConversationId: ID!, $convoLinkUserId: ID
  ) {
  createConvoLink(input: {
    convoLinkConversationId: $convoLinkConversationId, convoLinkUserId: $convoLinkUserId
  }) {
    id
    convoLinkUserId
    convoLinkConversationId
    conversation {
      id
      name
    }
  }
}
`;


이 네 가지 작업을 사용하여 앱이 작동하는 데 필요한 모든 데이터를 효과적으로 생성 할 수 있습니다. 데이터를 생성 한 후 쿼리하는 방법은 무엇입니까? 한번 보시죠.


Queries 



// Fetches a single user.
const getUser = `
  query getUser($id: ID!) {
    getUser(id: $id) {
      id
      username
    }
  }
`

// Fetches a single user as well as all of their conversations
const getUserAndConversations = `
  query getUserAndConversations($id:ID!) {
    getUser(id:$id) {
      id
      username
      conversations(limit: 100) {
        items {
          id
          conversation {
            id
            name
          }
        }
      }
    }
  }
`

// gets a single conversation based on ID
const getConvo = `
  query getConvo($id: ID!) {
    getConvo(id:$id) {
      id
      name
      members
      messages(limit: 100) {
        items {
          id
          content
          authorId
          messageConversationId
          createdAt
        }
      }
      createdAt
      updatedAt
    }
  }
`

// lists all of the users in the app
const listUsers = `
  query listUsers {
    listUsers {
      items {
        id
        username
        createdAt
      }
    }
  }
`


실시간 작품의 경우 2 개의 구독이 있습니다.


Subscriptions 

// When a new message is created, send an update to the client with the id, content, authorId, createdAt & messageConversationId fields
const onCreateMessage = `
  subscription onCreateMessage($messageConversationId: ID!) {
    onCreateMessage(messageConversationId: $messageConversationId) {
      id
      content
      authorId
      messageConversationId
      createdAt
    }
  }
`

// When a new user is created, send an update to the client with the id, username, & createdAt fields
const onCreateUser = `subscription OnCreateUser {
  onCreateUser {
    id
    username
    createdAt
  }
}
`;


State management 


Apollo / AppSync SDK 외부에서 진행되는 실제 상태 관리는 많지 않습니다. 그 밖에 구현 한 유일한 것은 MobX에 저장하여 동기식으로 사용자 데이터에 액세스하는 방법입니다. 앞으로는 이것을 Context로 바꾸거나 Apollo와 합병하고 싶습니다.


Offline 


오프라인 기능에 관한 한, 대부분의 경우 AWS AppSync JS SDK를 사용하고 있기 때문에 올바른 낙관적 업데이트를 제공하는 것 외에는 해야 할 일이 없습니다.


AppSync JS SDK는 기존 Apollo 캐시를 활용하여 오프라인 시나리오를 처리하고 오프라인에서 발생하는 모든 작업을 대기열에 추가합니다. 사용자가 다시 온라인 상태가 되면 업데이트가 생성 된 순서대로 서버로 전송됩니다.


결론 


이 앱을 빌드 할 때 구독 작업에 대해 많은 것을 배웠으며 앞서 언급 한 상태 관리와 같은 추가 기능을 AppSync SDK에서 완전히 처리 할 것입니다.


강력한 애플리케이션을 구축하기 위해 관리 형 서비스 및 API를 활용하는 이 철학에 대해 자세히 알아 보려면 서버리스 컴퓨팅 시대의 풀 스택 개발 게시물을 확인하십시오.


https://dev.to/dabit3/building-chatt---a-real-time-multi-user-graphql-chat-app-3jik




댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.