socket io 는 JSON 파일과 binary data form으로만 통신이 가능하다.
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
val gson.toJson(src : Any!)
를 이용한다
val gson = Gson()
// list, array, string, map 모두 가능
val gson.toJson("hello")
emit("event1", args)
: 이벤트를 만들고
on("event1", (args) => {})
: 이벤트를 받는다. 가 기본.
val message = et_message.text.toString()
mSocket.emit("chat message", gson.toJson(Student(
et_name.text.toString(), message)) )
socket.on('chat message', (item) => {
data = JSON.parse(item)
console.log(`${data.name} : ${data.message}`);
})
또는
val obj = JSONObject()
val message = et_message.text.toString()
mSocket.emit("chat message", gson.toJson(Student(
et_name.text.toString(), message)) )
socket.on('chat message', (data) => {
console.log(`${data.name} : ${data.message}`);
})
socket.emit('get message', {
name : data.name,
message : data.message
});
try{
val obj = JSONObject(args[0].toString())
val a = tv1.text.toString()
Log.d("chat activity", args[0].toString())
}catch(e : Exception){
e.printStackTrace()
}
이름을 받는 edittext, textview, message를 받는 edittext, message 를 전송하는 button 으로 구성된 간단한 안드로이드 뷰를 만들었다.
package com
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.gyoung.movierecord.R
import io.socket.client.IO
import io.socket.client.Socket
import io.socket.emitter.Emitter
import kotlinx.android.synthetic.main.activity_chat.*
import org.json.JSONObject
import java.lang.Exception
import java.net.URISyntaxException
class ChatActivity : AppCompatActivity() {
lateinit var mSocket : Socket;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
try{
mSocket = IO.socket("http://172.30.79.128:5000")
Log.d("chatActivity socket", "connected")
}catch(e : URISyntaxException){
Log.d("chatActivity socket", "failed")
}
button2.setOnClickListener {
val obj = JSONObject()
obj.put("name", et_name.text.toString())
obj.put("message", et_message.text.toString())
mSocket.emit("chat message", obj)
}
mSocket.on("get message", setMessage)
mSocket.connect();
}
var setMessage = Emitter.Listener { args ->
val obj = JSONObject(args[0].toString())
val a = tv1.text.toString()
Log.d("chat activity", obj.toString())
try{
tv1.text = a + "\n" + obj.get("name") + ": " + obj.get("message")
}catch(e : Exception){
e.printStackTrace()
}
}
}
const express = require('express');
const app = express();
const port = 5000;
const bodyParser = require('body-parser');
const socketIO = require('socket.io');
app.use(bodyParser.urlencoded({extended : true}));
app.use(bodyParser.json());
const server = app.listen(port, () => console.log('app listening on port ', port));
const io = socketIO.listen(server);
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('chat message', (data) => {
console.log(`${data.name} : ${data.message}`);
// 다른 유저들에게 보내기
socket.emit('get message', {
name : data.name,
message : data.message
});
})
socket.on('disconnect', () => {
console.log('user disconnected');
})
});
ui 는 메인스레드에서만 변경 가능한데, 새로운 스레드에서 textView 의 text를 변경시켜 에러가 발생.
textView 반영은 되는데 굉장히 느리게 반영된다.
try{
tv1.text = a + "\n" + obj.get("name") + ": " + obj.get("message")
}catch(e : Exception){
e.printStackTrace()
}
부분을
Thread(object : Runnable{
override fun run() {
runOnUiThread(Runnable {
kotlin.run {
tv1.text = a + "\n" + obj.get("name") + ": " + obj.get("message")
}
})
}
}).start()
로 바꿔서 ui Thread 에서 해당 구문을 처리하게 바꿔줬다.