ecsimsw

Socket connection 본문

Socket connection

JinHwan Kim 2019. 2. 27. 23:26

Socket connection

- 유니티에서 소켓 통신으로 멀티 플레이를 구현하는 방법을 공부해왔다.
-클라이언트에서 받은 입력으로 직접 게임을 동작시키는 것이 아니라 주체와 입력을 byte로 서버에 보내고 서버는 연결된 모든 클라이언트에 데이터를 수신. 그 후 다시 클라이언트는 데이터를 무한히 받기만 하는 다른 스레드를 만들어 데이터를 수신하고, 받은 데이터를 정류하여 어떤 주체가 어떤 입력을 했는지 확인 후 이를 처리하도록 하였다.
 
  • using Socket
    - 소켓을 다루기 위해 System.Net.Sockets Namespace를 선언한다.
    using System.Net.Sockets;
    - Tcpclient 객체와 받은 데이터를 저장할 string 변수를 private으로 선언한다.
    "Global" private NetworkStream stream; private TcpClient client; private string responseData = string.Empty;
      start 함수에서 Tcpclient를 ip주소와 port를 대입하여 인스턴스하고 스트림을 가져온다. 데이터를 무한히 받기위한 스레드를 생성한다.
    "Start()" client = new TcpClient(ipAddress, port); this.stream = client.GetStream(); thread = new Thread(new ThreadStart(ReceiveThread)); thread.Start();
  • Receive Thread
    - 서버에서 보내는 데이터를 무한히 대기하고 있을 스레드 함수를 정의한다. 스트림에서 바이트 데이터로 받아 원하는 데이터 형으로 캐스팅한다.
    "ReceiveThread()" void ReceiveThread() { while (true) { byte[] receiveData = new byte[256]; int bytes = stream.Read(receiveData, 0, receiveData.Length); responseData = Encoding.ASCII.GetString(receiveData, 0, bytes); } }
  • Handle Data
    - 받은 데이터를 정류하는 함수를 선언한다. 실습으로 만든 코드는 총 발사시 Shoot이라는 문자열을 송수신하는 간단한 경우만 만들어 보았다.
    "HandleData()" void HandleData(string Data) { switch (Data) { case "shoot": Shoot(); break; default: Debug.Log("Cannot read this Data"); break; } }
    - 유니티에서 메인 스레드가 아닌 다른 스레드에서 애니메이션을 플레이하는 것이 불가능하다는 오류가 출력됐다. Shoot 함수안에는 총알 발사 애니메이션을 플레이하기 때문에 HandleData를 데이터를 받는 스레드에서 바로 실행시킬 수 없다.
      정류한 변수를 초기화하고 메인 스레드에서 HandleData() 함수를 실행하기 위해 HandleInMainThread 함수를 선언하였다. Update()에서 실행되어 메인 스레드에서 데이터를 정류하고, 애니메이션을 처리하도록 한다.
    "HandleInMainThread()" void HandleInMainThread() { if (responseData != string.Empty) { HandleData(responseData); responseData = string.Empty; } }
  • Send Data()
    - 마우스 좌클릭시 Shoot이라는 문자열을 바이트로 변형하여 스트림에 쓴다. 이것으로 서버에 현재 클라이언트의 입력을 송신하는 것이다.
    "Send Data" if (Input.GetMouseButtonDown(0)){ string sendMsg = "shoot"; byte[] sendData = Encoding.ASCII.GetBytes(sendMsg); stream.Write(sendData, 0, sendData.Length); }
  • Node.js Server
    "server.js" var net = require('net'); var fs = require('fs'); var clients = new Array(); var server = net.createServer(function(socket){ clients.push(socket); socket.on('data',function(data){ for(var i=0; i<clients.length; i++){ clients[i].write(data); } }) socket.on('error', function(err) { console.log('Socket Error: ', JSON.stringify(err)); }); socket.on('end', function() { var end_socketIndex = clients.indexOf(socket); clients.splice(end_socketIndex, 1); console.log("left client : %d", clients.length); }); }) server.listen(3000,function(){ console.log("listen port : %d", server.address().port); })

'Etc > Unity' 카테고리의 다른 글

Coroutine  (0) 2019.03.07
Blend Tree  (0) 2019.02.25
Transition  (0) 2019.02.24
Mecanim  (0) 2019.02.23
Input Class / Input Manager / GetKey / GetButton  (0) 2019.02.22
Comments