Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ko #5

Open
wants to merge 9 commits into
base: ko
Choose a base branch
from
Open

Ko #5

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions doc/guide/ko/http_middleware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# HTTP Middleware

#### Warning: Incomplete. More to follow
#### 경고: 미완료. 더 수행해야 함.

SocketStream provides a stack of Connect HTTP middleware which is used internally to serve single-page clients, asset files and static files (e.g. images) in `client/static`.
SocketStream 은 싱글-페이지 클라이언트에게 `client/static` 안에 asset 파일들 과 static 파일 (예 이미지들) 서비스하기 위한 내부적으로 사용되는 Connect HTTP 미들웨어 스택을 제공합니다.

The Connect `app` instance is accessible directly via the `ss.http.middleware` variable within `app.js`.
그 Connect `app` 인스턴스는 `app.js`안에 `ss.http.middleware`변수를 통해 직접적으로 접근하는 것이 가능합니다.

SocketStream allows you
to prepend new middleware to the top of the stack (to be processed BEFORE SocketStream middleware) using:
SocketStream는 새로운 middleware가 스택의 꼭대기에 첨부 될수 있는 (SocketStream middleware 전에 처리하는) 사용을 허용한다:

ss.http.middleware.prepend()

For example you could add:
예를 들어 추가 할 수 있음:

ss.http.middleware.prepend( ss.http.connect.bodyParser() );

Because SocketStream adds `connect.cookieParser()` and `connect.session()` to the stack, if the middleware you're wanting to use requires sessions support (i.e. access to `req.session`) it will need to be appended to the bottom of the stack AFTER SocketStream middleware has been loaded as so:
만약 당신이 사용하고자 하는 미들웨어가 세션들의 지원을 요청하는 경우(즉, `req.session`로 접근), 왜냐하면 SocketStream은 `connect.cookieParser()` 과 `connect.session()`을 스택에 추가하기 때문에 로드된 SocketStream 미들웨어 후에 스택의 바닥에 삽입해야 할 것이다.

ss.http.middleware.append( everyauth.middleware() );

Apart from determining where the middleware should be added, the `prepend()` and `append()` functions work in exactly the same way as `connect.use()`.
미들웨어와 추가해야 하는 곳의 결정과는 별개로, `prepend()`과 `append()`함수 들은 정확히 `connect.use()` 와 같은 방법으로 동작합니다.
30 changes: 15 additions & 15 deletions doc/guide/ko/loading_assets_on_demand.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
<!---# Loading Assets On Demand-->
# �ʿ��Ҷ��� Assets�� �ҷ�����
<!---# Loading Assets On Demand-->
# 필요할때만 Assets을 불러오기


<!--If you're writing a small app you can safely ignore this section, as it's always better to pack all client assets into one file and send everything through together in one go if possible.-->

����� �ִ� ���� �۴ٸ�, �� �κ��� �dzʶپ �˴ϴ�. �ֳ��ϸ� �����ϸ�, Ŭ���̾�Ʈ�� ���� �� ���Ͽ��ٰ� ��Ƴ���, �� ���� ��� ������ ���� ���� �����Դϴ�.
만들고 있는 앱이 작다면, 이 부분은 건너뛰어도 됩니다. 왜냐하면 가능하면, 클라이언트의 에셋 한 파일에다가 모아놓고, 한 번에 모두 보내는 편이 낫기 때문입니다.

<!--But what if you're writing a large app, or an app with multiple distinct sections like iCloud.com?-->
�׷��� ����� �ִ� ���� ũ�ų�, ���� �����Ǵ� ���� ���� ������ ������ ��쿡�� ����? ���� ��� iCloud.com�� ���ó����.
그러나 만들고 있는 앱이 크거나, 서로 구별되는 여러 개의 섹션을 가지는 경우에는 어떨까요? 예를 들면 iCloud.com의 경우처럼요.

<!--SocketStream allows you to load code (and other assets in the future) into your app asynchronously on demand.-->
���Ͻ�Ʈ�������� ��û�� ���� ������ �񵿱����� ������� �ڵ带 �ۿ��ٰ� �ε��� �� �ֽ��ϴ�. ���߿��� �ٸ� ���µ� �̷��� �� �� ���� ���Դϴ�.
소켓스트림에서는 요청이 있을 때마다 비동기적인 방식으로 코드를 앱에다가 로드할 수 있습니다. 나중에는 다른 에셋도 이렇게 할 수 있을 것입니다.


<!---### Loading Code-->
### �ڵ带 �ε��ϱ�
### 코드를 로드하기

<!--Sadly it's not possible to directly `require()` modules which haven't been loaded as the blocking nature of the `require` function means the browser would freeze until the module has been retrieved from the server - not good.-->

��Ÿ���Ե�, �ε�Ǿ� ���� ���� ����� ���� `require()`�� ���� �����ϴ�. `require` �Լ��� �����κ��� ����� ������ ������ �������� ����ϴ�.
안타깝게도, 로드되어 있지 않은 모듈을 직접 `require()`할 수는 없습니다. `require` 함수는 서버로부터 모듈을 가져올 때까지 브라우저는 멈춥니다.

<!--However SocketStream allows you to load additional code modules from the server asynchronously using the built-in `ss.load.code()` command. Once all the code you've requested has been loaded, we execute a callback, allowing you to `require()` the new modules as normal without any fancy syntax.-->

������ ���Ͻ�Ʈ�������� `ss.load.code()` ���ɾ ����ؼ�, �񵿱������� �������� �߰����� �ڵ� ����� �ε��� �� �ֽ��ϴ�. �ϴ� �������� ��û�Ͻ� �ڵ尡 �� �ε�Ǹ�, ���Ͻ�Ʈ�������� �ݹ��� �����մϴ�. �׷��� Ư���� ������ ���� �ʾƵ�, `require()`�� ����ؼ� ���ο� ����� �ε��� �� �ֽ��ϴ�.
하지만 소켓스트림에서는 `ss.load.code()` 명령어를 사용해서, 비동기적으로 서버에서 추가적인 코드 모듈을 로드할 수 있습니다. 일단 여러분이 요청하신 코드가 다 로드되면, 소켓스트림에서는 콜백을 수행합니다. 그래서 특별한 구문을 쓰지 않아도, `require()`를 사용해서 새로운 모듈을 로드할 수 있습니다.

<!--To try this out, create a new directory of application modules in `/client/code`. For the sake of this example, let's call our new directory `/client/code/mail`. We'll also assume this directory has a module in it called `search.js`.-->
���� �غ�����. ���ø����̼� ��⿡ ����� ���ο� ������ `/client/code` ������ ���弼��. �׸��� ���ο� ������ `/client/code/mail`�̶�� �̸��� ���̼���. �� ���� �ȿ��� `search.js`��� ����� �ִٰ� �����ϰڽ��ϴ�.
직접 해보세요. 어플리케이션 모듈에 사용할 새로운 폴더를 `/client/code` 하위에 만드세요. 그리고 새로운 폴더에 `/client/code/mail`이라고 이름을 붙이세요. 이 폴더 안에는 `search.js`라는 모듈이 있다고 가정하겠습니다.
```javascript
//Ŭ���̾�Ʈ���� ���
//클라이언트쪽의 모듈
ss.load.code('/mail', function(){

// /client/code/mail �ȿ� ����ִ� ����� ��� �ε�Ǿ����ϴ�.
// ��Ʈ�� ���ӽ����̽��� (/)(??)�� ������ ������� ��û�� �� �ֽ��ϴ�.
// /client/code/mail 안에 들어있는 모듈이 모두 로드되었습니다.
// 루트의 네임스페이스인 (/)(??)는 보통의 방법으로 요청할 수 있습니다.

var search = require('/search');

Expand All @@ -45,11 +45,11 @@ ss.load.code('/mail', function(){

<!--Note: Regardless of the directory you load, the modules inside will always be loaded into the root (/) namespace by default. If you want to mount the new modules in a different namespace, just create one or more sub-directories in the folder you're loading.-->

�����ϼ���: �������� �ε��ϴ� ������ �������, ���� �ȿ� �ִ� ����� ������ ������ ������ �׻� ��Ʈ (/) �ȿ� �ε�� ���Դϴ�. ���ο� ����� �ٸ� ���ӽ����̽� �ȿ� ����Ʈ�Ͻ÷��� �ε��Ͻ÷��� ������ �ϳ� ����ų�, �ε��ϴ� ���� �ȿ� ���� ������ �ϳ� ���弼��.
주의하세요: 여러분이 로드하는 폴더와 상관없이, 폴더 안에 있는 모듈은 별도의 설정이 없으면 항상 루트 (/) 안에 로드될 것입니다. 새로운 모듈을 다른 네임스페이스 안에 마운트하시려면 로드하시려는 폴더를 하나 만들거나, 로드하는 폴더 안에 하위 폴더를 하나 만드세요.


<!---### Automatic Caching-->
### �ڵ� ij��
### 자동 캐싱

<!--Modules are only ever retrieved from the server once. Subsequent requests for the same directory will be returned instantly without contacting the server.-->
����� �����κ��� �� ���� �����ɴϴ�. ������ ������ ���� �� ���Ŀ� �̷������ ��û�� ������ �������� �ʰ� �ٷ� ��ȯ�˴ϴ�.
모듈은 서버로부터 한 번만 가져옵니다. 동일한 폴더에 대해 그 이후에 이루어지는 요청은 서버와 접속하지 않고 바로 반환됩니다.
159 changes: 159 additions & 0 deletions doc/guide/ko/pub_sub_events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Pub/Sub Events

SocketStream includes an powerful pub/sub system allowing you to easily send messages to connected browsers over the websocket.
SocketStream 은 연결된 웹브라우저에게 웹소켓으로 쉽게 메세지를 전송 할 수 있는 강력한 pub/sub시스템을 가지고 있습니다.

### 1. Sending to Everyone
### 1. 모두에게 보내기

To send an event to every connected client (for example to let them know the server's going down for maintenance), use the `ss.publish.all` method:
연결된 모든 브라우저에게 이벤트를 보내기 위해(예를 들어 서버가 유지보수를 위해 다운시켜야 함을 알리기 위해), `ss.publish.all`를 사용 함:

``` javascript
// in a /server/rpc file
ss.publish.all('flash', 'Notice: This service is going down in 10 minutes');
```
<!-- ss.publish.all('flash', '알림 : 10분 내로 이 서비스를 중지합니다.'); -->

Receive the event in the browser with:
브라우저에서 이벤트 받기:

``` javascript
// in a /client/code file
ss.event.on('flash', function(message){
alert(message);
});
```

Note: The first argument specifies the event name. All subsequent arguments will be passed through to the event handler.
노트: 첫번째 인자는 이벤트 이름으로 지정한다. 뒤이은 모든 인자들은 이벤트 핸들러에게 전달 되어질 것이다.


### 2. Sending to Private Channels
### 2. 프라이빗 채널로 전송하기

Sometimes you'll want to send events to a subset of connected clients. For example, you may have a chat app with multiple rooms.
가끔 접속된 일부 클라이언트에게만 이벤트를 전송하고 싶을 것입니다. 예를 들어, 여러개의 방에서 채팅하는 앱

Each client session can be subscribed to an unlimited number of private channels using the following commands:
다음에 명령을 사용하여 각각의 클라이언트 세션은 무제한으로 프라이빗 채널이 구독될 수 있습니다.(열려 질수 있습니다. 참조될 수 있습니다.)

``` javascript
// in a /server/rpc file after calling req.use('session') middleware

req.session.channel.subscribe('disney') // note: multiple channel names can be passed as an array

req.session.channel.unsubscribe('kids') // note: multiple channel names can be passed as an array

req.session.channel.reset() // unsubscribes the session from every channel

req.session.channel.list() // shows which channels the session is currently subscribed to
```
<!-- // /server/rpc 파일에서 req.use('session') 미들웨어를 호출 후에 -->


Sending a message to a private channel is similar to broadcasting to all; however, note the first argument now specifies the channel name (or channels if you pass an array):
프라이빗 채널로 메세지를 전송 하는 것은 모두에게 브로드캐스팅(전송)하는 것과 비슷함; 하지만, 첫번째 인자에 채널(또는 채널들 채널 배열로 기록)이름을 기록 함:

``` javascript
// in a /server/rpc file
ss.publish.channel('disney', 'chatMessage', {from: 'jerry', message: 'Has anyone seen Tom?'});
```

Receive these events in the browser in the usual way. Note: If the event was sent to a channel, the channel name is passed as the final argument to the event handler:
이일반 적인 방법으로 브라우저에서 이러한 이벤트를 받음. 노트: 채널로 이벤트가 보내진다면, 채널이름은 마지막 인자로 이벤트 핸들러에 전달 됨 :


``` javascript
// in a /client/code file
ss.event.on('chatMessage', function(msg, channelName){
console.log('The following message was sent to the ' + channelName + ' channel:', msg);
});
```
<!-- console.log('다음은 받은 메세지 ' + channelName + ' channel:', msg); -->

### 3. Sending to Users
### 3. 사용자들에게 보내기

Once a user has been [authenticated](https://github.com/socketstream/socketstream/blob/master/doc/guide/en/authentication.md) (which basically means their session now includes a value for `req.session.userId`), you can message the user directly by passing the `userId` (or an array of IDs) to the first argument of `ss.publish.user` as so:
한번이라도 인증이 되어지면(기본적으로 사용자의 현재 세션은 `req.session.userId`의 값을 포함 하는 것을 의미 함), `ss.publish.user`의 첫번째 인자에 `userId`(또는 ID들의 배열)을 (삽입하여) 사용자에게 직접 메세지를 보낼 수 있습니다.


``` javascript
// in a /server/rpc file
ss.publish.user('fred', 'specialOffer', 'Here is a special offer just for you!');
```
<!-- ss.publish.user('가카', '빅엿', '여기 당신을 위한 빅엿이 있습니다.'); -->
<!-- 취향에 맞게 바꾸셈.. -->

### 4. Sending to Individual Clients (browser tabs)
### 4. 개체 각각의 클라이언트에게 전송하기 (브라우저 탭들)

If a user opens multiple tabs in the browser, each will share the same `req.session.id` and private channel subscriptions (as channels are attached to sessions).
만약 사용자가 브라우저로 복수의 탭을 열은 경우, 각각은 `req.session.id` 과 프라이빗 채널 구독(참조) 를 공유합니다.(채널들이 세션에 첨부된 되어 있으므로)


Normally this is the desired behavior, but in rare cases you'll want to message a particular client (i.e. a individual browser tab):
일반적으로 이것은 올바른 동작이지만, 드문 경우지만 개개의 클라이언트에게 메세지를 보내길 원할 수 있습니다. (예 각각의 브라우저 탭):
<!-- 의미상 Individual 을 각각의 로 표현 == particular : 개개의 -->

``` javascript
// in a /server/rpc file
ss.publish.socketId('254987654324567', 'justForMe', 'Just for one tab');
```
<!-- // /server/rpc 파일 에서 -->

You can find the socketId by calling `req.socketId` in your server-side code. Note, this attribute may not always be present (e.g. if you invoke the RPC method via `ss-console`), so plan accordingly.
당신은 서버측 코드에서 `req.socketId` 호출 하여 socketId를 찾을 수 있습니다. 노트: 이 속성은 항상 존재하지 않을 수 있으므로 적절히 계획하시오.(예: `ss-console`으로 RPC메소드 호출)

Please be aware that `req.socketId` will change if you refresh the page, so it's much better to assign clients to private channels and use those wherever possible.
페이지가 새로고침 되면 `req.socketId`는 변경될 걸 이라는 걸 인식했으면 하며, 그래서 가능한 모든때에 클라이언트들에게 프라이빗 채널들을 할당하고 그것울 이 용하는 것이 훨씬 낫다.


### Publishing Events via app.js
### app.js를 통해 이벤트 발행하기

Sometimes you'll want to publish events from outside your `/server/rpc` files, such as your `app.js` file. The entire `ss` API available to actions in `/server/rpc` is also available in `app.js` via the `ss.api` object. Hence to publish an event to `all` you would call:
떄떄로 `app.js`처럼 /server/rpc`파일 외부에서 이벤트들을 발생하길 원할 수 있을 것이다. /server/rpc`에서 action들에 사용할 수 있는 전체의 `ss` API는 `ss.api`의 객체를 통해 `app.js`에서 또한 이용 할 수 있다. 따라서 모두에게 이벤트를 게시하기 위해 당신은 호출 해야 함:

``` javascript
// in /app.js
ss.api.publish.all()
```


### Event Transports
### 이벤트 수송


By default SocketStream sends all published events over an internal event emitter. This works fine during development and under moderate load, however; once your app outgrows a single process, you'll need to switch to an external event transport to allow you to run multiple SocketStream processes/servers at once.
모든 게시된 이벤트들은 내부의 이벤트 emitter(게시자)를 통해 기본적인 SocketStream으로 보내집니다. 이것은 개발단계 와 약간의 부하에서도 잘 동작하지만; 일단 당신의 앱이 싱글 프로세스를 벗어나게 되면, 당신은 한번에 여러 프로세스들/서버들이 한번에 실행할 수 있도록 외부의 이벤트를 수송하도록 전환할 필요가 있을 것입니다.

Event transports are implemented in a modular way, so it's possible to write a simple driver to support any Message Queue.
이벤트 수송은 모듈방식으로 구현될 수 있어서 어떤 메세지 큐를든지 지원 할 수 있는 간단한 드라이버 형태로 작성될 수 있습니다.

To use the in-built Redis transport (recommended), add the following line to your `app.js` file:
(추천하는)내장된 Redis 수송을 사용하기 위해, 다음 라인을 당신의 `app.js`추가:

``` javascript
// in app.js
ss.publish.transport.use('redis'); // any config can be passed to the second argument
```
<!-- ss.publish.transport.use('redis'); // 모든 설정은 두번쨰 인자로 전달됩니다. -->

Using an external event transport has an important added benefit: Now you can easily push events to connected browser from external (non Node.js) systems. Simply connect the external system (e.g. an Erlang service) to the same instance of Redis and publish messages using the same JSON message format.
외부 이벤트 수송을 이용하면 중요한 잇점이 있습니다: 지금 외부 시스템(Node.js는 아니고)으로부터 연결된 브라우저에게 쉽게 이벤트를 보낼수 있습니다. JSON 메세지 포멧을 이용하여 외부 시스템과 같은 인스턴스, 게시한 메세지를 간단히 연결한다.(예 Erlang 서비스)


**Notes**
**노트**

1. If the channel name you specify does not exist it will be automatically created. Channel names can be any valid JavaScript object key. If the client gets disconnected and re-connects to another server instance they will automatically be re-subscribed to the same channels, providing they retain the same `sessionId`. Be sure to catch for any errors when using these commands.
1. 지정한 채널이름이 존재하지 않는 경우 자동으로 생성되 것입니다. 채널 이름들은 유효한 JavaScript 객채 키가 될 수 있습니다. 접속이 끈긴 클라이언트가 다른 서버 인스턴스로 재 접속을 하는 경우 그것들이 가지고 있는 같은`sessionId`가 제공하기 때문에 그것들은 자동적으로 같은 채널들로 재-구독(재-참조) 될 것입니다.

2. The SocketStream Pub/Sub system has been designed from the ground up with horizontal scalability and high-throughput in mind. The `all` and `channel` commands will be automatically load-balanced across all SocketStream servers when an external event transport is used.
2. SocketStream Pub/Sub시스템음 수평 확장성 과 높은 처리량을 염두해 두고 하위에서 상향으로 설계되었습니다. `all`과 `channel`명령어들은 외부의 이벤트 수송이 사용되어 질 때 자동적으로 모든 SocketStream 서버들 간의 로드-밸런싱(균형-조정)될 것입니다.

3. It is important to remember messages are never stored or logged. This means if a client/user is offline the message will be lost rather than queued. Hence, if you're implementing a real time chat app we recommend storing messages in a database (or messaging server) before publishing them.

3. 그것은 로그를 남기거나 메세지를 저장하지 않는 것을 기억하는 점이 중요합니다. 이것은 클라리언트/사용자가 오프라인에 되면 메세지를 싫어 버리기 보다는 오히려 큐에 적제된 상태를 의미합니다. 그러므로 실시간 채팅앱을 구현하는 경우 메세지를 게시하기 전에 데이터베이스에(또는 메세징 서버에) 저장하는 것을 추천합니다.
Loading