HTML52014. 6. 20. 15:36


http://www.elabs.se/blog/66-using-websockets-in-native-ios-and-android-apps

이 샘플은 WebSocket으로 실시간으로 browser, iOS, android 클라이언트와 통신하는 방법에 대한 것이다.

서버는 웹소켓서버를 운영하고 여러가지 플랫폼과 통신을 수행이 가능해진다. 전체 소스는  https://github.com/elabs/mobile-websocket-example 을 참고하라.


서버

아주 간단한 웹소켓서버의 예는 아래와 같다.EM-WebSocket gem을 사용하고 Ruby로 구현되었다.


equire "em-websocket" EventMachine.run do @channel = EM::Channel.new EventMachine::WebSocket.start(host: "0.0.0.0", port: 8080, debug: true) do |ws| ws.onopen do sid = @channel.subscribe { |msg| ws.send(msg) } @channel.push("#{sid} connected") ws.onmessage { |msg| @channel.push("<#{sid}> #{msg}") } ws.onclose { @channel.unsubscribe(sid) } end end 

end 

웹소켓연결을 8080포트에서 수락한고 새로운 클라이언트가 연결되면 내부 채널을 구독한다. 클라이언트가 데이터를 이 채널에 전송하여 채널에 데이터가 유효해질때마다 모든 클라이언트에 데이터를 전송한다. 클라이언트는 구독ID를 통해 구별이 가능하다. 클라이언트가 연결이 끊어지면 채널의 구독을 중단한다.

위코드를 실행하려면 bundle install , ruby server.rb을 순서대로 실행한다.

Browser client


$(document).ready(function() { ws = new WebSocket("ws://" + location.hostname + ":8080/"); ws.onmessage = function(event) { $("#messages").append("<p>" + event.data + "</p>"); }; ws.onclose = function() { console.log("Socket closed"); }; ws.onopen = function() { console.log("Connected"); ws.send("Hello from " + navigator.userAgent); }; $("#new-message").bind("submit", function(event) { event.preventDefault(); ws.send($("#message-text").val()); $("#message-text").val(""); }); 

}); 

서버에 8080포트로 연결을 하고 연결이 되었을 때, 메세지가 도달하였을 때, 그리고 연결이 닫혔을떄의 콜백을 구현하였다.

새로운 메세지를 작성하고 메세지를 전송하기 위한 submit form도 작성하였다.

이 코드는 모던브라우져만 지원한다. 오래된 브라우져에서는 Flash로 가능하다.


iOS client

SocketRocket이라는 라이브러리로 웹소켓을 사용할 수 있다. 이것은 Cocoapods로 설치가 가능하다. 먼저 Cocoapods를 설치해야 한다.

Podfile을 아래와 같이 iOS프로젝트가 있는 폴더에서 만든다.

platform :ios, "7.0"

pos "SocketRocket" 

Cocoapods가 설치되어 잇지 않다면 gem install cocoapods 을 실행하고 pod setup을 실행 이어서 pod install을 Podfile이 들어 있는 iOS프로젝트 폴더에서 실행한다.

관련 코드는 ViewController.m에 웹소켓서버에 연결하는 코드를 작성한다.


-(void) connectWebSocket {

  webSocket.delegate = nil;

  webSocket = nil;

  NSString *urlString = @"ws://localhost:8080";

  SRWebSocket *newWebSocket  = [[SRWebSocket alloc] initWithURL initWithURL:[NSURL URLWithString:urlString]];

  newWebSocket.delegate = self;

  [newWebSocket open];
}

localhost부분을 서버주소로 바꾸면 된다. 

다음은 SRWebSocketDelegete protocol의 구현이다.

- (void)webSocketDidOpen:(SRWebSocket *)newWebSocket {

  webSocket = newWebSocket;

  [webSocket send:[NSString stringWithFormat:@"Hello from %@", [UIDevice currentDevice].name]];

}

- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {

  [self connectWebSocket];

}

- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean {

  [self connectWebSocket];

}

- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {

  self.messagesTextView.text = [NSString stringWithFormat:@"%@\n%@", self.messagesTextView.text, message];

} 

브라우져에서 사용하는 자바스크립트 API와 완전 비슷하다.

메세지를 보낼때는 다음과 같이


-(IBAction)sendMessage:(id)sender {

  [webSocket send:self.messageTextField.text];

  self.messageTextField.text =nil;

} 


Android client

Android Studio를 사용한다면 Java WebSockets라이브러리를 gradle로 설치한다

dependencies {

  compile "org.java-websocket:Java-WebSocket:1.3.0"

} 

ADT를 사용한다면 maven으로 java WebSocket을 설치하던가 아니면 별도로 배포되는 jar을 받아서 사용하던가 하면 된다


private void connectWebSocket() {

  URI uri;

  try {

    uri = new URI("ws://websockethost:8080");

  } catch (URISyntaxException e) {

    e.printStackTrace();

    return;

  }


  mWebSocketClient = new WebSocketClient(uri) {

    @Override

    public void onOpen(ServerHandshake serverHandshake) {

      Log.i("Websocket", "Opened");

      mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL);

    }


    @Override

    public void onMessage(String s) {

      final String message = s;

      runOnUiThread(new Runnable() {

        @Override

        public void run() {

          TextView textView = (TextView)findViewById(R.id.messages);

          textView.setText(textView.getText() + "\n" + message);

        }

      });

    }


    @Override

    public void onClose(int i, String s, boolean b) {

      Log.i("Websocket", "Closed " + s);

    }


    @Override

    public void onError(Exception e) {

      Log.i("Websocket", "Error " + e.getMessage());

    }

  };

  mWebSocketClient.connect();

} 

websockethost는 수정하라.

메세지 보 낼때는 이렇게

public void sendMessage(View view) {

  EditText editText = (EditText)findViewById(R.id.message);

  mWebSocketClient.send(editText.getText().toString());

  editText.setText("");

}

android.permission.INTERNET권한이 있어야 하고 앱타겟을 Android 4.0+이다.













Posted by 삼스