Android-socket.IO

2 분 소요

Android & socket.io

android 설정

  1. 빌드 및 라이브러리 설정

(1) build.gradle(Project) 파일 수정

classpath “com.android.tools.build:gradle:4.0.1”

(2) build.gradle(Module:app) 파일 수정

API level 29

compileSdkVersion 29

(3) dependencies추가

implementation ‘com.github.nkzawa:socket.io-client:0.6.0’

  1. 인터넷 관련 설정

(1) 인터넷 권한 추가 (AndroidManifest.xml )

  <uses-permission android:name="android.permission.INTERNET" />

(2)네트워크 보안 설정

9.0부터(API 28이상)는 네트워크 보안구성 일반 텍스트 트래픽 사용을 지원기능(HTTPS 대신 암호화되지 않은 HTTP 프로토콜 사용) 중지

  <application ...
  android:networkSecurityConfig="@xml/network_security_config"
  ... </application>

(3) network_security_config.xml생성

res밑에 xml폴더 생성 후 network_security_config.xml 파일 생성하고 다음 입력 res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!--Set application-wide security config using base-config tag.-->
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

#

Node.JS 서버 (app.js)

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
    console.log('a user connected');
    socket.on('disconnect', function(){
      console.log('user disconnected');
    });

    socket.on('msg', function(msg){
        console.log('message: ' + msg);
        io.emit('msg', msg);
    });
});

http.listen(8080, function(){
  console.log('listening on *:8080');
});

#

웹 클라이언트 (index.html)

<!doctype html>
<html>
  <head>
    <title>Client Socket</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0 0 50px 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>

    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
            $(function () {
              var socket = io();
              $('form').submit(function(e){
                e.preventDefault(); // prevents page reloading
                socket.emit('msg', $('#m').val());
                $('#m').val('');
                return false;
              });
              socket.on('msg', function(msg){
                $('#messages').append($('<li>').append($('<pre>').text(msg)));
                $('html, body').scrollTop($(document).height());
              });
            });
          </script>
  </body>
</html>

#

android (client 소스코드)

package com.example.socket_android_200922;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.URISyntaxException;


public class MainActivity extends AppCompatActivity {

    private Socket mSocket;
    {
        try {
            mSocket = IO.socket("http://192.168.0.30:8080");
        } catch (URISyntaxException e) {
        }
    }

    Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSocket.on("msg", onMessage);
        mSocket.connect();
        Log.e("result socket connect", String.valueOf(mSocket.connected()));
        Log.e("result socket connect", String.valueOf(mSocket.connect()));

        btn = (Button)findViewById(R.id.sendBtn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                /*mSocket.on("msg", onMessage);
                mSocket.connect();
                Log.e("result socket connect", String.valueOf(mSocket.connected()));
                Log.e("result socket connect", String.valueOf(mSocket.connect()));*/

                mSocket.emit("msg", "hi");
                Log.e("send", "data");

            }
        });

        /*
        JSONObject data = new JSONObject();
        try {
            data.put("username", "홍길동");
            data.put("message", "헬로 월드");
            mSocket.emit("msg", data);
        } catch(JSONException e) {
            e.printStackTrace();
        }*/
    }

    private Emitter.Listener onMessage = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String data=(String)args[0];
                    Log.e("get", data);
                    /*
                    JSONObject data = (JSONObject) args[0];
                    String username;
                    String message;
                    try {
                        username = data.getString("username");
                        message = data.getString("message");
                    } catch (JSONException e) {
                        return;
                    }*/
                    // 메시지를 받으면 data에 담고,
                    // username와 message라는 키값으로 들어왔다는 가정으로 작성된 코드다.
                    // addMessage(username, message); 이런 식으로 코드를 실행시키면 addMessage 쪽으로 인자를 담아 보내니 화면에 노출하게 만들면 될 것이다.

                }
            });
        }
    };
}

참고

https://developer.android.com/training/articles/security-config?hl=ko http://kimboomin.blogspot.com/2018/11/android.html

댓글남기기