Pusher는 WebSocket 프로토콜을 기반으로 한 멋진 기능을 갖춘 쉽고 신뢰할 수 있는 플랫폼입니다: 유연한 pub/sub 메시징, 실시간 사용자 목록(presence), 인증 등.
Pusher WebSocket API는 7입니다.
데이터는 UTF8로 인코딩된 JSON을 포함하는 텍스트 데이터로 WebSocket을 통해 양방향으로 전송됩니다(바이너리 WebSocket 프레임은 지원되지 않습니다).
Ping 메서드를 호출하여 서버에 대한 연결을 테스트할 수 있습니다. 본질적으로 상대방으로부터 수신된 모든 메시지는 연결이 살아 있음을 의미하는 것으로 간주됩니다. 메시지가 없는 경우 어느 한쪽이 ping 메시지를 보내 상대방이 응답하는지 확인할 수 있으며, 상대방은 pong으로 응답해야 합니다.
연결하기 전에 다음 필드를 작성해야 합니다.
Pusher.Cluster := 'eu'; // cluster where your pusher account is located
Pusher.Key := '9c3b7ef25qe97a00116c'; // your pusher api key
Pusher.Name := 'js'; // optional, name of your application
Pusher.Version := '4.1'; // optional, version of your application
Pusher.TLS := True; // if encrypted, set to True
Pusher.Secret := '2dc792e1916ac49e6b3f'; // pusher secret string (needed for private and presence channels)
중요
Pusher는 websocket 클라이언트가 이전 필드(key, cluster...)를 사용하여 URL에 연결할 것을 요구합니다. 이 필드들은 url을 빌드하는 데 사용되며, pusher 구성 요소에 클라이언트를 할당할 때 수행됩니다. 따라서 URL이 올바르게 빌드되도록 하려면 pusher 구성 필드를 채운 후 클라이언트를 설정하십시오. 아래에서 의사 코드를 확인하십시오:
// configure pusher fields
pusher.cluster = ...
pusher.key = ...
// set client
pusher.client = websocket client
// start connection
websocket client.Active = true;
성공적인 연결 후 OnPusherConnect 이벤트가 발생하고 다음 필드를 받습니다:
Socket ID: 연결된 클라이언트의 고유 식별자.
Timeout: 클라이언트가 ping 메시지를 시작해야 하는 서버 비활성 시간(초)입니다(이는 구성 요소에서 자동으로 처리됩니다).
오류 발생 시 OnPusherError가 발생하고 오류에 대한 정보가 제공됩니다. 오류는 유효하지 않은 인증, 유효하지 않은 명령 등에 대한 응답으로 Pusher에서 전송될 수 있습니다.
4000-4099
Pusher에 의해 연결이 닫히는 결과를 초래하는 오류를 나타내며, 동일한 매개변수를 사용하여 재연결을 시도해도 성공하지 못함을 나타냅니다.
4000: 애플리케이션이 SSL 연결만 수락하므로 wss://를 사용하여 다시 연결하십시오
4001: 애플리케이션이 존재하지 않습니다
4003: 애플리케이션 비활성화됨
4004: 애플리케이션이 연결 할당량을 초과했습니다
4005: 경로를 찾을 수 없음
4006: 잘못된 버전 문자열 형식
4007: 지원되지 않는 프로토콜 버전
4008: 프로토콜 버전이 제공되지 않음
4100-4199
Pusher가 연결을 닫는 결과를 초래하는 오류를 나타내며, 클라이언트가 1초 이상 후에 재연결할 수 있음을 나타냅니다.
4100: 용량 초과
4200-4299
Pusher가 연결을 닫게 되는 오류를 나타내며, 클라이언트가 즉시 다시 연결할 수 있음을 나타냅니다.
4200: 즉시 일반 재연결
4201: Pong 응답을 받지 못함: 클라이언트에 ping을 보냈으나 응답을 받지 못함 - ping 및 pong 메시지를 참조하십시오.
4202: 비활성으로 인해 종료됨: 클라이언트가 오랫동안(현재 24시간) 비활성 상태였으며 ping을 지원하지 않습니다. 최신 WebSocket draft로 업그레이드하거나 이 프로토콜의 버전 5 이상을 구현하십시오.
4300-4399
다른 모든 유형의 오류입니다.
4301: 속도 제한으로 인해 클라이언트 이벤트가 거부됨
채널은 Pusher의 기본 개념입니다. 각 애플리케이션에는 여러 채널이 있으며, 각 클라이언트는 어떤 채널을 구독할지 선택할 수 있습니다.
채널은 다음을 제공합니다:
데이터를 필터링하는 방법입니다. 예를 들어, 채팅 애플리케이션에서 'dogs'에 대해 논의하려는 사람들을 위한 채널이 있을 수 있습니다.
다양한 정보 스트림에 대한 액세스를 제어하는 방법입니다. 예를 들어, 프로젝트 관리 애플리케이션은 사람들이 'projectX'에 대한 업데이트를 받을 수 있도록 권한을 부여하려고 할 것입니다.
이벤트가 아니라 채널을 사용하여 데이터를 필터링하는 것이 강력히 권장됩니다. 이는 채널에 게시된 모든 이벤트가 이벤트 바인딩에 관계없이 모든 구독자에게 전송되기 때문입니다.
채널은 명시적으로 생성할 필요가 없으며 클라이언트 요청 시 인스턴스화됩니다. 즉, 채널 생성이 쉽습니다. 클라이언트에게 구독하도록 지시하기만 하면 됩니다.
다음 유형의 채널이 지원됩니다:
공개 채널은 이름을 아는 누구나 구독할 수 있습니다.
Private 채널은 브로드캐스트하는 데이터에 대한 액세스를 서버가 제어할 수 있게 하는 메커니즘을 도입합니다
Presence 채널은 private 채널의 확장입니다. 구독 시 사용자 정보를 등록할 수 있고, 채널의 다른 멤버에게 누가 온라인인지 알릴 수 있습니다
Cache 채널은 마지막으로 트리거된 이벤트를 기억하고 새 구독자에게 첫 번째 이벤트로 전송합니다(public, private 및 presence 변형)
Private-Encrypted 채널은 NaCl secretbox를 사용하여 종단간 암호화를 제공하므로 Pusher조차도 메시지 데이터를 읽을 수 없습니다
public 채널은 구독하기 위해 어떤 형태의 권한 부여도 필요하지 않으므로 공개적으로 액세스 가능한 데이터에 사용해야 합니다.
언제든지 채널을 구독하고 구독 취소할 수 있습니다. Pusher가 먼저 연결을 완료할 때까지 기다릴 필요가 없습니다.
예제: 채널 "my-channel"을 구독합니다.
Delphi
APIPusher.Subscribe('my-channel');
구독에 성공하면 OnPusherSubscribe 이벤트가 발생하고, 오류가 있으면 OnPusherError 이벤트에서 메시지를 받습니다.
구독된 채널의 모든 메시지는 OnPusherEvent 이벤트에서 수신됩니다.
Publish 메서드가 호출되고 채널이 Public인 경우, 구성 요소는 WebSocket 프로토콜을 사용하는 대신 HTTP 프로토콜을 사용하여 TriggerEvent 메서드를 호출합니다(websocket 프로토콜을 사용한 publish는 허용되지 않음).
Indy 10.5.7 이상이 필요합니다
프라이빗 채널은 채널에 대한 접근을 어떤 식으로든 제한해야 할 때 사용해야 합니다. 사용자가 프라이빗 채널을 구독하려면 권한이 승인되어야 합니다.
예제: 채널 "my-private-channel"을 구독합니다.
Delphi
APIPusher.Subscribe('my-private-channel', pscPrivateChannel);
구독에 성공하면 OnPusherSubscribe 이벤트가 발생하고, 오류가 있으면 OnPusherError 이벤트에서 메시지를 받습니다.
구독된 채널의 모든 메시지는 OnPusherEvent 이벤트에서 수신됩니다.
Indy 10.5.7 이상이 필요합니다
Presence 채널은 Private 채널의 보안을 기반으로 하며 누가 해당 채널을 구독하고 있는지에 대한 인식이라는 추가 기능을 노출합니다. 이를 통해 채팅방 및 "온라인 상태" 유형 기능을 애플리케이션에 매우 쉽게 구축할 수 있습니다. 채팅방, 문서 공동 작업자, 동일한 웹 페이지를 보는 사람들, 게임의 경쟁자 등을 생각해 보십시오.
Presence 채널은 private 채널과 동일한 방식으로 클라이언트 API에서 구독되지만, 채널 이름 앞에 presence-를 붙여야 합니다. private 채널과 마찬가지로 현재 사용자가 채널에 접근할 권한이 있는지 확인하기 위해 구성 가능한 인증 URL로 HTTP 요청이 이루어집니다.
채널을 구독하고 구독 취소하는 사용자에 대한 정보는 presence 채널의 이벤트에 바인딩하여 접근할 수 있으며, 채널을 구독한 사용자의 현재 상태는 channel.members 속성을 통해 사용할 수 있습니다.
예제: "my-presence-channel" 채널을 구독합니다.
APIPusher.Subscribe('my-presence-channel', pscPresenceChannel,
'{"user_id":"John_Smith","user_info":{"name":"John Smith"}}')
구독에 성공하면 OnPusherSubscribe 이벤트가 발생하고, 오류가 있으면 OnPusherError 이벤트에서 메시지를 받습니다.
구독된 채널의 모든 메시지는 OnPusherEvent 이벤트에서 수신됩니다.
캐시 채널은 마지막으로 트리거된 이벤트를 기억하고 이를 새 구독자에게 첫 번째 이벤트로 보냅니다.
cache 채널에서 이벤트가 트리거되면 Pusher Channels는 이 이벤트를 캐시하고, 클라이언트가 cache 채널을 구독할 때 캐시된 값이 존재하면 해당 채널의 첫 번째 이벤트로 클라이언트에 전송됩니다. 이 동작은 개발자가 다른 곳에서 가져오는 추가 로직을 추가하지 않고도 초기 상태를 제공하는 데 도움이 됩니다.
다음 Cache 채널이 지원됩니다:
예제: 공개 캐시 채널 "my-cache-channel"을 구독합니다.
APIPusher.Subscribe('my-cache-channel', pscCacheChannel);
구독에 성공하면 OnPusherSubscribe 이벤트가 발생하고, 오류가 있으면 OnPusherError 이벤트에서 메시지를 받습니다.
구독된 채널의 모든 메시지는 OnPusherEvent 이벤트에서 수신됩니다.
cache 채널을 구독할 때 캐시된 이벤트가 없으면 OnPusherCacheMiss 이벤트가 발생하여 채널 이름을 제공합니다. 이를 통해 애플리케이션은 캐시된 데이터가 없는 경우를 처리할 수 있습니다.
Private-Encrypted 채널은 메시지에 대한 종단간 암호화를 제공합니다. private 채널과 마찬가지로 인증이 필요하지만, 추가로 모든 데이터 페이로드가 NaCl secretbox를 사용하여 암호화되므로 권한이 부여된 구독자만 콘텐츠를 읽을 수 있습니다. Pusher 자체도 메시지를 복호화할 수 없습니다.
private-encrypted 채널을 사용하려면 인증 중에 SharedSecret을 제공해야 합니다. 공유 비밀은 메시지 데이터를 암호화하고 복호화하는 데 사용됩니다.
Example: private-encrypted 채널 "my-encrypted-channel"을 구독합니다.
APIPusher.Subscribe('my-encrypted-channel', pscPrivateEncryptedChannel);
암호화와 캐시 채널 동작을 결합한 private-encrypted-cache 변형도 사용할 수 있습니다:
APIPusher.Subscribe('my-encrypted-cache-channel', pscPrivateEncryptedCacheChannel);
private-encrypted 채널에서 OnPusherAuthentication 이벤트를 사용할 때, 응답 객체의 SharedSecret 속성을 설정하여 암호화 키를 제공할 수 있습니다:
procedure OnPusherAuthenticationEvent(Sender: TObject;
AuthRequest: TsgcWSPusherRequestAuthentication;
AuthResponse: TsgcWSPusherResponseAuthentication);
begin
AuthResponse.SharedSecret := 'your-shared-secret-key';
end;
Presence 채널은 사용자가 채널에 가입하거나 떠날 때 애플리케이션에 알리는 추가 이벤트를 제공하며, 구독 수를 추적할 수 있게 합니다.
새 멤버가 presence 채널을 구독할 때 발생합니다. 가입한 멤버의 채널 이름, 사용자 ID 및 사용자 정보를 제공합니다.
procedure PUSHERPusherMemberAdded(Sender: TObject;
Channel, UserId, UserInfo: string);
begin
Log('Member joined: ' + UserId + ' on ' + Channel);
end;
멤버가 presence 채널에서 구독을 취소할 때 발생합니다. 떠난 멤버의 채널 이름, 사용자 ID 및 사용자 정보를 제공합니다.
procedure PUSHERPusherMemberRemoved(Sender: TObject;
Channel, UserId, UserInfo: string);
begin
Log('Member left: ' + UserId + ' on ' + Channel);
end;
채널의 구독 수가 변경될 때 발생합니다. 채널 이름과 현재 구독자 수를 제공합니다. 이 이벤트는 Pusher 대시보드에서 활성화되어야 합니다.
procedure PUSHERPusherSubscriptionCount(Sender: TObject;
Channel: string; SubscriptionCount: Integer);
begin
Log(Channel + ' has ' + IntToStr(SubscriptionCount) + ' subscribers');
end;
캐시된 이벤트가 없는 캐시 채널을 구독할 때 발생합니다. 채널 이름을 제공합니다. 이를 통해 애플리케이션이 캐시된 데이터가 없는 경우를 처리할 수 있습니다(예: 다른 소스에서 데이터를 가져옴).
procedure PUSHERPusherCacheMiss(Sender: TObject; Channel: string);
begin
Log('Cache miss on: ' + Channel);
end;
구독한 채널에서 메시지를 수신할 수 있을 뿐만 아니라, 다른 구독 사용자에게 메시지를 보낼 수도 있습니다.
채널의 모든 구독 사용자에게 메시지를 보내려면 Publish 메서드를 호출하십시오.
예시: "my-channel"의 구독된 모든 사용자에게 이벤트 전송
APIPusher.Publish('my-event', 'my-channel');
클라이언트(연결)당 초당 10개 이하의 메시지를 게시하십시오. 이 속도 제한을 초과하여 트리거된 이벤트는 Pusher API에 의해 거부됩니다. 이것은 시스템 문제가 아니라 클라이언트 문제입니다. 한 채널에 있는 100개의 클라이언트가 이 속도로 메시지를 보내면 각자 초당 1,000개의 메시지를 처리해야 합니다! 일부 최신 브라우저는 이를 처리할 수 있을지 모르지만 대부분 좋은 생각은 아닙니다.
API는 http://api-CLUSTER.pusher.com 에서 호스팅되며, 여기서 CLUSTER는 자신의 앱 클러스터(예: eu)로 대체됩니다.
HTTP 상태 코드는 요청의 성공 여부를 나타내는 데 사용됩니다. 다음 상태가 일반적입니다:
200 성공적인 요청. 본문에는 응답 데이터의 JSON 해시가 포함됩니다
400 오류: 자세한 내용은 응답 본문에 있습니다.
401 인증 오류: 응답 본문에 설명이 포함됩니다
403 Forbidden: 앱이 비활성화되었거나 메시지 할당량 초과
다음 REST API 함수가 구현되었습니다.
| Function | 설명 |
| TriggerEvent | 지정된 채널에서 새 이벤트를 트리거합니다. 선택적 SocketId(클라이언트를 제외하기 위함) 및 Info 매개변수를 지원합니다. |
| TriggerBatchEvents | 단일 HTTP 요청으로 여러 이벤트를 트리거합니다. 이벤트 객체의 JSON 배열을 허용합니다. |
| GetChannels | 모든 활성 채널의 목록을 제공합니다. 선택적 FilterByPrefix 및 Info 매개변수를 지원합니다. |
| GetChannel | 특정 채널에 대한 정보를 제공합니다. 선택적 Info 매개변수를 지원합니다. |
| GetUsers | 채널에 연결된 모든 사용자의 목록을 제공합니다. |
| TerminateUserConnections | 사용자 ID로 식별되는 특정 사용자의 모든 연결을 종료합니다. |
하나 이상의 채널에서 이벤트를 트리거합니다. 이벤트 이름, 채널 이름, 데이터 페이로드가 필요합니다.
| Parameter | 설명 |
| aEventName | 트리거할 이벤트의 이름. |
| aChannel | 이벤트를 트리거할 채널 이름입니다. |
| aData | 이벤트 데이터(JSON 문자열)입니다. |
| aSocketId (선택적) | 이벤트 수신에서 제외할 소켓 ID입니다. 발신자가 자신의 메시지를 받지 않도록 하는 데 유용합니다. |
| aInfo (선택적) | 응답에 포함할 속성의 쉼표로 구분된 목록입니다(예: "subscription_count"). |
// trigger event on a channel
APIPusher.TriggerEvent('my-event', 'my-channel', 'Hello World');
// trigger event excluding the sender
APIPusher.TriggerEvent('my-event', 'my-channel', 'Hello World', '123.456');
// trigger event requesting subscription_count in the response
APIPusher.TriggerEvent('my-event', 'my-channel', 'Hello World', '', 'subscription_count');
단일 API 호출로 여러 이벤트를 트리거하며, 이는 각 이벤트에 대해 별도의 요청을 하는 것보다 효율적입니다. batch 매개변수는 이벤트 객체의 배열을 포함하는 JSON 문자열이어야 하며, 각 객체는 "channel", "name" 및 "data" 필드를 가집니다.
APIPusher.TriggerBatchEvents(
'[{"channel":"my-channel","name":"my-event","data":"hello"},' +
'{"channel":"my-channel-2","name":"my-event","data":"world"}]');
활성 채널 목록을 반환합니다. 결과를 필터링하고 추가 정보를 요청하기 위한 선택적 매개변수를 지원합니다.
| Parameter | 설명 |
| aFilterByPrefix (선택적) | 이름 접두사로 채널을 필터링합니다(예: presence 채널만 나열하려면 "presence-"). |
| aInfo (선택적) | 응답에 포함할 속성의 쉼표로 구분된 목록(예: "user_count"). |
// get all channels
APIPusher.GetChannels;
// get only presence channels with user count
APIPusher.GetChannels('presence-', 'user_count');
특정 채널에 대한 정보를 반환합니다.
| Parameter | 설명 |
| aChannel | 정보를 가져올 채널 이름입니다. |
| aInfo (선택적) | 포함할 속성의 쉼표로 구분된 목록입니다(예: "user_count,subscription_count"). |
// get channel info
APIPusher.GetChannel('presence-my-channel');
// get channel info with user count
APIPusher.GetChannel('presence-my-channel', 'user_count,subscription_count');
presence 채널에 연결된 사용자 목록을 반환합니다. 채널 이름에는 전체 접두사가 포함되어야 합니다(예: "presence-my-channel").
APIPusher.GetUsers('presence-my-channel');
주어진 사용자가 설정한 모든 연결을 종료합니다. 이는 특정 사용자가 모든 채널에서 연결을 끊도록 강제하는 데 사용할 수 있습니다. 사용자 ID는 사용자가 presence 채널을 구독할 때 사용한 "user_id"와 일치해야 합니다.
APIPusher.TerminateUserConnections('1234');
Pusher는 private 또는 presence 채널에 대한 구독만 허용합니다. 연결이 인증 토큰을 제공하면 액세스를 제한할 수 있습니다.
OnPusherAuthentication 이벤트를 사용하여 자체 인증 흐름을 구축할 수 있습니다. 이 이벤트는 구독 메시지가 Pusher가 제공한 비밀 키로 서명되기 전에 호출됩니다. 이 이벤트에는 SocketId, 채널 이름 등의 필드가 있는 요청 인증과 같은 2개의 매개변수가 있으며, 이는 자체 인증 서버에서 요청을 인증하거나 인증하지 않는 데 사용할 수 있습니다. 아래에서 pusher 인증 흐름을 보여주는 스크린샷을 찾을 수 있습니다

클라이언트가 pusher 서버에 연결하면, pusher가 제공한 Key를 보내고 서버는 식별 id(socket_id)를 반환합니다.
클라이언트가 private(또는 presence) 채널을 구독하면, sgcWebSockets 클라이언트는 pusher가 제공한 Secret Key를 사용하여 구독 메시지에 포함되는 서명을 생성합니다. OnPusherAutentication 이벤트를 사용하여 메시지 서명에 필요한 필드를 캡처하고, 자체 인증 방법을 구현하고, 성공하면 서명을 반환하면, 이 서명이 구독 메시지에 포함되어 서버로 전송됩니다.
예제:
oClient := TsgcWebSocketClient.Create(nil);
oPusher := TsgcWSAPI_Pusher.Create(nil);
oPusher.Client := oClient;
oPusher.Cluster := 'eu';
Pusher.Name := 'js';
Pusher.Version := '4.1';
Pusher.TLS := True;
Pusher.Key := '9c3b7ef25qe97a00116c';
Pusher.Secret := ''; // the secret key is not known by the client, only by the authentication module
oPusher.OnPusherAuthentication := OnPusherAuthenticationEvent;
procedure OnPusherAuthenticationEvent(Sender: TObject; AuthRequest: TsgcWSPusherRequestAuthentication;
AuthResponse: TsgcWSPusherResponseAuthentication);
begin
// if the authentication request is successful return the signature
if CustomAuthentication(AuthRequest.Channel, AuthRequest.SocketID) then
AuthResponse.Signature := GetCustomAuthenticationSignature;
end;
서명의 형식은 다음과 같습니다:
비공개 채널: key:HMAC256(SocketID, ChannelName)
Presence 채널: key: HMAC256(SocketID, ChannelName, Data)
TsgcWSPusherResponseAuthentication 객체는 다음 속성을 제공합니다:
| 속성 | 설명 |
| Secret | HMAC 서명을 계산하는 데 사용되는 Pusher 비밀 키. 구성된 경우 Pusher.Secret로 미리 채워집니다. |
| 서명 | 계산된 인증 서명입니다. 비워 두면 구성 요소가 Secret을 사용하여 자동으로 계산합니다. |
| SharedSecret | private-encrypted 채널에 대한 공유 시크릿 키입니다. pscPrivateEncryptedChannel 또는 pscPrivateEncryptedCacheChannel을 구독할 때 필요합니다. 메시지 데이터의 종단간 암호화에 사용됩니다. |