블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2795)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (61)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

(http://link2me.tistory.com 에서 발췌)

기타 : split를 string문자열로 자를때 word_1.Split(new string[] {"\\"}, StringSplitOptions.None) C# Split함수의 경우 직접 문자열을 구분자로 줄수 없다.

Split 은 기본적으로 문자를 입력 받도록 되어 있다. 문자열을 char[]형식으로 변경 후 사용 가능하다.

 

string str = "서울시/서초구/양재동";
string[] result = str.Split(new char[] { '/' });  // /   열 result  라.
for (int i = 0; i < result.Length ; i++)  // 은 0  며,   
{
    MessageBox.Show(i + "번째 배열 ==> " + result[i]);
}

 

string str = "jsk005@naver.com";
char[] sp ="@".ToCharArray();
string[] result = str.Split(sp);
for (int i = 0; i < result.Length; i++)
{
    MessageBox.Show(i + "번째 배열 ==> " + result[i]);
}

 

string str = "홍 길 동";
string[] result = str.Split(new char[] {' '});  // new char[] {}  도 공백으로 나눈다는 의미
for (int i = 0; i < result.Length; i++)
{
    MessageBox.Show(i + "번째 배열 ==> " + result[i]);
}

 

위의 예제와 아래 예제의 차이점을 보면 split  자(char)  열(string)이다. 

string 으로 할 경우에는 반드시 StringSplitOptions.None 또는 StringSplitOptions.RemoveEmptyEntries 까지 추가해줘야만 에러가 발생하지 않는다. 물론 위의 것도 StringSplitOptions 를 추가해줘도 된다.

 

string str = "홍길동~~~이순신~~~강감찬~~~을지문덕";
string[] result = str.Split(new string[] {"~~~"}, StringSplitOptions.None);
for (int i = 0; i < result.Length; i++)
{
    MessageBox.Show(i + "번째 배열 ==> " + result[i]);
}

string[] separator = new string[1] { "\r\n\r\n" };  //분리할 기준 문자열
string[] strResult = s.Split(separator, StringSplitOptions.RemoveEmptyEntries);

  

* StringSplitOptions.None  //     

* StringSplitOptions.RemoveEmptyEntries  // 반환값에 빈 부분 문자열 포함 안됨

 

foreach (string strValue in strResult)
{
    
}

또는 

for (var i =0 ; i < strResult.Length ; i++) 

{

}

 

//구     

string str = "[stop]ONE[stop][stop]TWO[stop][stop][stop]THREE[stop][stop]";
string[] stringSeparators = new string[] { "[stop]" };
string[] result = str.Split(stringSeparators, StringSplitOptions.None);

for (int i = 0; i < result.Length; i++)
{
    if (String.IsNullOrEmpty(result[i]))  //  null  
    {
        MessageBox.Show("null" + result[i]);
    }
    else
    {
        MessageBox.Show(i + "번째 배열 ==> " + result[i]);
    }                
} 

 

아래와 같이StringSplitOptions.RemoveEmptyEntries 으로 수정하면 결과가 어떻게 나올까?

string str = "[stop]ONE[stop][stop]TWO[stop][stop][stop]THREE[stop][stop]";
string[] stringSeparators = new string[] { "[stop]" };
string[] result = str.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);  

// 반환값에 빈 부분 문자열 포함 안됨
for (int i = 0; i < result.Length; i++)
{
    if (String.IsNullOrEmpty(result[i]))
    {
        MessageBox.Show("null" + result[i]);
    }
    else
    {
        MessageBox.Show(i + "번째 배열 ==> " + result[i]);
    }                
} 

결과는 null 이나 공백은 무시되므로 배열은 0, 1, 2 만 추출된다.



   

System.Text.RegularExpressions.Regex.Split(자를 문자열, 정규식 문자열)

using System;
using System.Text.RegularExpressions;

 

string str = "cat\r\ndog\r\nanimal\r\nperson";
string[] result = Regex.Split(str, "\r\n");
for (int i = 0; i < result.Length; i++)
{
    MessageBox.Show(i + "번째 배열 ==> " + result[i]);
} 



포함된 문자열의 개수 구하기
int
 count = source.Split('/').Length - 1;

 

[출처] http://hunq.blogspot.com/2016/09/c-split.html

반응형
Posted by blueasa
, |

NIST 타임서버에서 시간가져오기 (NST)

아래와 같은 코드로 가져올 수 있다.
Unity 에서 사용할 수 있다.

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TimeServer : MonoBehaviour {

    [SerializeField]
    private string _comment = "만료시킬 날짜를 적으세요 (한국시각 기준)";

    public int _yyyy, _mm, _dd;
    private DateTime _expireDateTime, _nowServerDateTime, _nowLocalDateTime;
    private TimeSpan _duration;

 // Use this for initialization
 void Start () {

        // 한국 시각
        _duration = System.TimeSpan.FromHours(9);
        _expireDateTime = new DateTime(Mathf.Clamp(_yyyy, 1900, 3000), Mathf.Clamp(_mm, 1,12), Mathf.Clamp(_dd, 1, 31));

        _nowLocalDateTime = DateTime.Now;
        _nowServerDateTime = GetNISTDate().Add(_duration);

        if (Debug.isDebugBuild)
        {
            Debug.LogWarning("만료지정일 : " + _expireDateTime);
            Debug.LogWarning("현재 로컬 시각 :" + _nowLocalDateTime);
            Debug.LogWarning("현재 서버 시각 :" + _nowServerDateTime);
        }

        if (_nowLocalDateTime < _expireDateTime)
        {
            if (_nowServerDateTime < _expireDateTime)
            {
                // Debug.Log("실행");
            }
            else
            {
                // Debug.Log("서버 체크 결과 만료 됨");
            }
        }
        else
        {
            // Debug.Log("로컬 체크 결과 만료 됨");
        }


    }

#region NTPTIME

    //NTP time 을 NIST 에서 가져오기
    // 4초 이내에 한번 이상 요청 하면, ip가 차단됩니다.

    public static DateTime GetDummyDate()
    {
        return new DateTime(2017, 12, 24); //to check if we have an online date or not.
    }

    public static DateTime GetNISTDate()
    {
        System.Random ran = new System.Random(DateTime.Now.Millisecond);
        DateTime date = GetDummyDate();
        string serverResponse = string.Empty;

        // NIST 서버 목록
        string[] servers = new string[] {
        "time.bora.net",
        //"time.nuri.net",
        //"ntp.kornet.net",
        //"time.kriss.re.kr",
        //"time.nist.gov",
        //"maths.kaist.ac.kr",
        "nist1-ny.ustiming.org",
        "time-a.nist.gov",
        "nist1-chi.ustiming.org",
        "time.nist.gov",
        "ntp-nist.ldsbc.edu",
        "nist1-la.ustiming.org"
    };

        // 너무 많은 요청으로 인한 차단을 피하기 위해 한 서버씩 순환한다. 5번만 시도한다.
        for (int i = 0; i < 5; i++)
        {
            try
            {
                // StreamReader(무작위 서버)
                StreamReader reader = new StreamReader(new System.Net.Sockets.TcpClient(servers[ran.Next(0, servers.Length)], 13).GetStream());
                serverResponse = reader.ReadToEnd();
                reader.Close();

                // 서버 리스폰스를 표시한다. (디버그 확인용)
                if (Debug.isDebugBuild)
                    Debug.Log(serverResponse);

                // 시그니처가 있는지 확인한다.
                if (serverResponse.Length > 47 && serverResponse.Substring(38, 9).Equals("UTC(NIST)"))
                {
                    // 날짜 파싱
                    int jd = int.Parse(serverResponse.Substring(1, 5));
                    int yr = int.Parse(serverResponse.Substring(7, 2));
                    int mo = int.Parse(serverResponse.Substring(10, 2));
                    int dy = int.Parse(serverResponse.Substring(13, 2));
                    int hr = int.Parse(serverResponse.Substring(16, 2));
                    int mm = int.Parse(serverResponse.Substring(19, 2));
                    int sc = int.Parse(serverResponse.Substring(22, 2));

                    if (jd > 51544)
                        yr += 2000;
                    else
                        yr += 1999;

                    date = new DateTime(yr, mo, dy, hr, mm, sc);

                    // Exit the loop
                    break;
                }
            }
            catch (Exception e)
            {
                /* 아무것도 하지 않고 다음 서버를 시도한다. */
            }
        }
        return date;
    }
    #endregion
}

아래 코드 원본에서 주석 변경 및 내가 사용하기 위해 수정함.
경로 : https://stackoverflow.com/questions/516788/getting-current-gmt-time

 

[출처] http://blog.kpaper.com/2017/10/unity-nst-nist.html

반응형
Posted by blueasa
, |
반응형
Posted by blueasa
, |
반응형
Posted by blueasa
, |

dependency 걸려 있는 파일이 없다는 내용.

Unity에서 Firebase Analytics 패키지 추가 후에 해당 에러가 나서 이런 저런 테스트 결과 아래와 같이 해결 했음.

 

1) Assets >> Play Services Resolver >> Android Resolver >> Resolve 실행

2) Unity3D 에디터 재시작

 

[출처] https://github.com/firebase/quickstart-unity/issues/44

 

Authentication: "One or more Firebase dependencies are not present" · Issue #44 · firebase/quickstart-unity

When I start the authentication app in Android, I receive the error below: "One or more Firebase dependencies are not present. Current dependency status: UnavailableOther" Can someone hel...

github.com

 

반응형
Posted by blueasa
, |

[링크] https://bitbucket.org/vitaly_chashin/simpleunitybrowser

반응형
Posted by blueasa
, |

[Link] https://github.com/Yortw/Yort.Ntp

반응형
Posted by blueasa
, |


[링크]

https://themangs.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0%EB%9E%91-nodejs-%EA%B0%84%EB%8B%A8-%EC%97%B0%EB%8F%99-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%95%B4%EB%B3%B4%EA%B8%B0


[링크2]

https://github.com/NetEase/UnitySocketIO

반응형

'Unity3D > Plugins' 카테고리의 다른 글

[링크] FancyScrollView (CoverFlow)  (0) 2019.04.24
[링크] Simple Unity browser  (0) 2019.03.28
[펌] Socket.io-Client for Unity3D 소개  (0) 2019.03.08
[링크] iOSPlugin Sample  (0) 2019.01.29
[펌] Unity Excel Importer  (0) 2019.01.03
Posted by blueasa
, |


image.png

들어가면서

socket.io

웹 환경에서는 클라이언트인 브라우저와 서버 간에 푸쉬나 실시간 데이터를 처리하는데 여러 가지 방법을 활용했습니다. 그중에 Ajax를 이용한 polling, Long polling과 Streaming의 특징은 다음 그림과 같이 비교할 수 있습니다.

image.png
출처 : https://blogs.oracle.com/theaquarium/entry/slideshow_example_using_comet_dojo

위와 같은 방식을 활용하다가 나온 표준이 Websocket입니다. Websocket은 기존에 게임 개발자들이 활용하고 있던 TCP socket과 비슷하게 데이터를 주고 받을 수 있으며 Polling보다 자유롭게 데이터를 주고 받을 수 있게 되었습니다. Webocket에 대해 좀더 자세한 내용을 원하시면 여기 링크(https://ko.wikipedia.org/wiki/웹소켓) 를 참조 부탁드립니다. 하지만 이 좋은 Websocket의 단점은 지원하는 브라우저가 없을 수 있다는 점이 입니다. 이런 단점을 보완 하고자 브라우저와 상관 없이 웹에서 실시간으로 데이터를 처리 할수 있게 도와주는 것이 바로 socket.io입니다. socket.io(http://socket.io)는 Guillermo Rauch에의해 LearnBoost라는 회사가 개발했으며 MIT 라이선스의 오픈소스입니다.

socket.io는 WebSocket, FlashSocket, JSONP과 Long Polling을 하나로 묶어 브라우저에서 Websocket을 지원하지 않더라도 실시간 데이터처리를 돕습니다. 다양한 브라우저에서 데이터를 처리하기 위한 방법 뿐만 아니라 데이터를 주고 받기 위한 메세지 규약, 연결 유지를 위한 핑퐁 등과 같이 socket 연결을 위해 기본으로 구현해야할 부분까지 처리가 되어있기 때문에 서비스 개발자는 실시간 데이터 처리만 집중할 수 있습니다. socket.io의 프로토콜 정의는 링크 https://github.com/socketio/socket.io-protocol와 https://github.com/socketio/engine.io-protocol 참조 하시면 됩니다.

socket.io-Client

요 근래 게임에서도 실시간으로 데이터를 처리 하기 위해 Websocket을 많이 활용하는 추세 입니다. 왜냐하면 TCP socket보다 단순하게 구현할 수 있기 때문입니다. 실제로 Unity3d에서 WebGL로 빌드 할 때에도 데이터를 주고 받는 방법으로 Websocket을 이용하고 있습니다. socket보다 구현하기 쉬운 Websocket도 사실 데이터처리가 용의할 뿐 연결을 체결하거나 유지하는 등의 네트워크 레이어는 개발자가 직접 구현해야 합니다. 하지만 socket.io를 이용하면 연결과 기본적인 프로토콜이 구현되어 있기 때문에 개발자는 컨텐츠 데이터를 주고 받는데만 집중할 수 있습니다.

socket.io는 다양한 언어를 지원합니다. Javascript는 물론이고, Java, Swift와 CPP을 지원합니다. 지원하는 언어는 아래와 같습니다.

개발 하기까지

우리 회사에는 풋볼데이와 야구9단과 같은 웹 게임을 개발하면서 데이터를 push해주기 위해 socket.io를 이용했습니다. 기존의 socket.io구현체는 Node.js를 활용한 구현체 였지만 우리회사는 JAVA를 활용하여 대용량 트래픽 처리와 보안 인증을 추가한 플랫폼으로 구현했습니다. 해당 플랫폼을 사내 공용 플랫폼화 하여 웹 게임 뿐만 아니라 다른 서비스에도 적용하였고, 웹과 네이티브 앱간의 데이터 통신하는데 활용하고 있습니다.

기존의 socket.io 클라이언트 들은 다양한 네이티브 언어를 지원하고 있으나 게임개발에 많이 활용되고 있는 unity3d는 지원하지 않습니다. 우리는 우리의 플랫폼을 게임에도 활용하여 게임 개발자들에게 데이터 처리를 위해 네트워크를 개발하는 수고를 덜어주고 싶었습니다. 서버는 우리 회사의 플랫폼도 있고 오픈소스인 socket.io node.js용 서버도 있으니 클라이언트만 있다면 게임 개발자들도 쉽게 개발 할수 있을 것 같았습니다. 하지만 기존의 unity3d용 라이브러리들은 0.9버전이거나 유지 보수가 되지 않아서 우리가 직접 socket.io-Client Unity3D 라이브러리를 개발하게 되었습니다.

socket.io 사용법

실제로 Node.js + socket.io-Client Unity3D를 이용하여 구현된 샘플 코드를 살펴보면서 socket.io 사용법을 소개하겠습니다. 서버/클라이언트 코드로 구성되며 서버 코드는 socket.io 공식 홈페이지에서 발췌/변경하였습니다. socket.io 공식 홈페이지는 아래 링크를 확인해주세요.
socket.io 공식 홈페이지

추가로 Node.js로 직접 서버 코드를 실행해보고 싶으신 분들은 아래 링크를 참조하여서 서버 개발 환경 셋팅을 할 수 있습니다.
Node.js and Visual Studio Code End to End

예제를 구현하기 위한 소스는 아래 링크에서 찾아 보실 수 있습니다.

Connect to Server

첫번째 해야할 것은 역시나 컨넥션을 맺는 것입니다. 서버는 우선 HTTP 서버를 오픈해야합니다. 이는 socket.io 클라이언트가 최초엔 Polling 모드로 접속을 시도하도록 구현되어 있기 때문입니다.

서버 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Server~/connection.js]
var app = require('http').createServer(handler)
var fs = require('fs');

app.listen(4444);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
      if (err) {
          res.writeHead(500);
          return res.end('Error loading index.html');
      }

      res.writeHead(200);
      res.end(data);
  });
}

// socket.io 스타트
var io = require('socket.io')(app);

// 클라이언트 컨넥션 이벤트 처리
io.on('connection', function (socket) {
  console.log('Hello, socket.io~');
});

Socket.io가 시작되는 것은 'socket.io' 모듈을 가져올 때, 원샷에 처리가 됩니다. 이 때, 인자값으로 HTTP 서버의 인스턴스 (app 변수)를 추가해주면 HTTP 서버의 주소로 Socket.io가 Bind되면서 자동으로 Listen을 시작합니다. 이 때, 리턴하는 io 변수는 일종의 매니저 객체로써 이를 통해서 실제 세션에 해당하는 socket 객체를 획득할 수 있습니다. io.on() 메소드에서 'connection'이라는 이벤트를 핸들링하도록 구현했고, 클라이언트에서 컨넥션이 완료되었을 때, 콜백 함수를 통해서 socket을 획득할 수 있습니다. socket은 일종의 세션 객체라고 생각해도 무방합니다. socket을 통해서 앞으로 각종 패킷을 Send/Receive하게 됩니다.

클라이언트 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Client/Src/Connection.cs]
using UnityEngine;
using socket.io;

namespace Sample {

    public class Connection : MonoBehaviour {

        void Start() {
            // 접속 Url
            var serverUrl = "http://localhost:4444";

            // 서버로 접속 시도~
            var socket = Socket.Connect(serverUrl);

            // 접속 완료 이벤트 처리
            socket.On("connect", () => {
                Debug.Log("Hello, socket.io~");
            });
        }

    }

}

클라이언트는 socket.io.Socket 클래스의 Connect() 메소드를 호출합니다. 이 때 인자값으로 서버의 Url을 입력합니다. 접속이 성공하면, socket 변수를 리턴하고 서버와 동일하게 각종 패킷을 Send/Receive하게 됩니다. 예제 코드에서는 'connect' 이벤트를 캐치하여 웰컴 메세지를 출력하도록 구현해보았습니다.

Event 핸들링

socket.io는 Event 기반으로써 모든 통신의 처리는 'Event 등록 + Callback 함수 구현'의 형식으로 구현됩니다. Event를 Send하는 메소드는 Emit(), 그리고 Event를 Receive하는 메소드는 On()입니다. 아래 예제를 보면서 좀 더 자세히 살펴보겠습니다.

서버 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Server~/events.js]
// HTTP 서버 코드는 생략 (...)

// socket.io 스타트
var io = require('socket.io')(app);

// 클라이언트 컨넥션 이벤트 처리
io.on('connection', function (socket) {

    // 'news' 이벤트 send
    socket.emit('news', { hello: 'world' });

    // 'my other event' 이벤트 receive
    socket.on('my other event', function(data) {
        console.log(data);
    });

});
클라이언트 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Client/Src/Events.cs]
using UnityEngine;
using socket.io;

namespace Sample {

    public class Events : MonoBehaviour {

        void Start() {
            var serverUrl = "http://localhost:4444";
            var socket = Socket.Connect(serverUrl);

            // "news" 이벤트 처리 Receive
            socket.On("news", (string data) => {
                Debug.Log(data);

                // "my other event" 이벤트 Send
                socket.Emit(
                    "my other event",       // 이벤트명
                    "{ \"my\": \"data\" }"  // 데이터 (Json 텍스트)
                    );
            });
        }

    }

}

2개의 이벤트를 정의하여 서버와 클라이언트 간의 패킷 송수신을 구현했습니다. 서버는 'news' 이벤트를 Send하고 'my other event'를 Receive합니다. 클라이언트는 반대입니다.

실행 결과
  • 서버
    image.png
  • 클라이언트
    image.png

Emit() 메소드

Send를 담당하는 Emit() 메소드는 다음과 같은 형식을 같습니다.

public void Emit(string evtName, string data);
  • Emit() 파라메터
evtNamedata
이벤트 이름이벤트 데이터 (주로 Json 객체)

On() 메소드

Receive를 담당하는 On() 메소드의 정의는 다음과 같습니다.

public void On(string evtName, Action<string> callback);
  • On() 파라메터
evtNamecallback
이벤트 이름이벤트 핸들러 함수

System Event

Emit()과 On() 메소드에서 선언한 이벤트 이름 중 일부 문자열은 시스템 예약어이므로 사용을 금지합니다. 서버 용 시스템 이벤트는 아래 링크에서 확인이 가능합니다.

[https://socket\.io/docs/server\-api/\]\(socket\.io Server API)

여기서는 클라이언트 용 시스템 이벤트만 정리해보겠습니다.

이벤트 이름콜백 파라메터비고
connect없음접속 완료
connectTimeOut없음시간 초과로 인한 접속 실패
reconnectAttempt없음재접속 시도
reconnectFailed없음재접속 실패
reconnectint (재접속 횟수)재접속 완료
reconnectingint (재접속 횟수)재접속 중
connectErrorException접속 실패
reconnectErrorException재접속 실패

콜백 파라메터를 기준으로 On() 메소드 호출 형식이 바뀌게 됩니다. 예를 들어 'reconnect' 이벤트를 핸들링하고 싶다면 다음과 같이 코드를 작성해야 합니다.

socket.On("reconnect", (int attempt) => {
    Debug.LogFormat("Reconnected after {0} trials, attempt);
});

Event Ack

이번엔 이벤트를 Send하고 이에 대한 응답을 Receive하는 방법을 알아보겠습니다.

서버 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Server~/acks.js]
// HTTP 서버 코드는 생략 (...)

// socket.io 스타트
var io = require('socket.io')(app);

// 클라이언트 컨넥션 이벤트 처리
io.on('connection', function (socket) { 

   socket.on('ferret', function (name, fn) {
        // 'woot' 문자열을 Ack 메세지로 보냄
        fn('woot');
    }); 
});
클라이언트 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Client/Src/Acks.cs]
using UnityEngine;
using socket.io;

namespace Sample {

    public class Acks : MonoBehaviour {

        void Start() {
            var serverUrl = "http://localhost:4444";
            var socket = Socket.Connect(serverUrl);

            socket.On("connect", () => {

                // "ferret" 이벤트 Send
                socket.Emit(
                    "ferret", "\"toby\"", 
                    (string ackData) => { Debug.Log(ackData); } // 3번째 인자로 콜백을 셋팅하면 Ack 모드로 동작하며 Ack 시에 콜백이 호출됨
                    );
            });
        }

    }

}

앞서 소개한 Event 핸들링 예제와 달라진 점은 클라이언트 코드에서 Emit() 메소드에 3번째 인자로 콜백을 추가한 것입니다. 이렇게 호출하게 되면 Ack 모드로 Emit() 메소드가 동작하게 됩니다. 위의 예제에서는 서버 코드에서 Ack 메시지로 'woot' 문자열을 리턴하였고, 클라이언트는 Ack 콜백에서 'woot' 문자열을 인자값으로 받게 됩니다.

Namespace

하나의 소켓을 논리적인 처리 단위로 구분할 수 있습니다. Multiplexing이라고도 불리는 이러한 패턴을 통해서 하나의 커넥션(소켓 인스턴스)에서 여러 개의 독립적인 코드를 개발할 수 있습니다.

서버 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Server~/namespace.js]
// HTTP 서버 코드는 생략 (...)

// socket.io 스타트
var io = require('socket.io')(app);

// chat 네임스페이스
var chat = io
  .of('/chat')
  .on('connection', function (socket) {
    chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
    socket.emit('a message', { that: 'only', '/chat': 'will get' });
  });

// news 네임스페이스
var news = io
  .of('/news')
  .on('connection', function (socket) {
    socket.emit('item', { news: 'item' });
  });
클라이언트 코드 [https://github.com/nhnent/socket.io-client-unity3d/blob/master/Assets/__Sample/Client/Src/Namespace.cs]
using UnityEngine;
using socket.io;

namespace Sample {

    public class Namespace : MonoBehaviour {

        void Start() {
            var serverUrl = "http://localhost:4444";

            // news 네임스페이스
            var news = Socket.Connect(serverUrl + "/news");
            news.On("connect", () => {
                news.Emit("woot");
            });
            news.On("a message", (string data) => {
                Debug.Log("news => " + data);
            });
            news.On("item", (string data) => {
                Debug.Log(data);
            });

            // chat 네임스페이스
            var chat = Socket.Connect(serverUrl + "/chat");
            chat.On("connect", () => {
                chat.Emit("hi~");
            });
            chat.On("a message", (string data) => {
                Debug.Log("chat => " + data);
            });
        }

    }

}

서버는 of() 메소드를 통해서 네임스페이스를 선언합니다. 클라이언트는 단순히 Url에 주소를 추가하는 것으로 선언이 가능합니다. 위 예제에선 "http://localhost:4444/chat"과 "http://localhost:4444/news"와 같이 chat과 news 네임스페이스를 선언하였습니다. 그 외에 나머지는 일반적인 이벤트 핸들링과 동일합니다.

실행 결과

image.png

위 예제의 포인트는 클라이언트 코드에서 chat과 news이 모두 'a message' 이벤트를 등록하였지만 오직 chat 소켓만이 'a message' 이벤트를 핸들링하게 되는 점입니다. 네임스페이스로 구분하여 이벤트명을 중복하여 사용하는 것이 가능하다라는 것을 시사하며 이를 통해서 채널 혹은 컨텐츠 개발 스코프마다 각각 네임스페이스르 할당해서 작업한다면 하나의 소켓 컨넥션 안에서도 이벤트 이름의 충돌없이 코드 작성이 가능하게 됩니다.

결론

오랫동안 게임 개발에서는 Socket을 이용한 네트워크를 구현해 왔습니다. 하지만 socket을 이용하여 데이터를 주고 받기 위해서는 네트워크의 연결 유지와 데이터 전송을 위해 너무 많은 노력이 필요합니다. 게임 개발에 있어서 어려운 네트워크 구현을 빼고 컨텐츠 개발에 힘을 쓴다면 더 좋은 게임이 나올 것이라 생각됩니다. 더욱이 웹과 같은 다양한 플랫폼을 지원 하는 게임을 개발하는데 있어 네트워크 레이어마다 개발을 해야한다면 좀더 좋은 게임을 개발할 수 있는시간을 빼앗기게 됩니다. 그래서 우리는 게임 개발자들이 데이터 통신에 많은 시간을 투자하지 않고 게임을 개발 할수 있도록 socket.io를 위한 Unity3d를 MIT라이선스로 공개하기로 했습니다. socket.io-client-unity3d를 활용하여 좀더 컨텐츠 개발에 시간을 투자하고, 하나의 서버 플랫폼을 이용해 다양한 클라이언트 플랫폼을 지원 하는데 도움이 되었으면 좋겠습니다.

해당 라이브러리에 관심이 있으신분들은 https://github.com/nhnent/socket.io-client-unity3d에서 확인 하실 수 있습니다. 또한 참여하시고 싶으신 분들은 https://github.com/nhnent/socket.io-client-unity3d/blob/master/CONTRIBUTING.md를 참조하셔서 참여하여 주시면 감사하겠습니다.


[출처]

https://meetup.toast.com/posts/112



[추가]

socket.io v2.x에서 수정해야 될 내용

https://github.com/nhnent/socket.io-client-unity3d/commit/48b1fb6e743ff2228942a6e08f2eb9a73e1ff2a0


[추가2]

socket.io https 대응 (출처: shmhlove)

https://github.com/shmhlove/Asgardium_Client/tree/develop/Assets/Plugins/socket.io

반응형

'Unity3D > Plugins' 카테고리의 다른 글

[링크] Simple Unity browser  (0) 2019.03.28
[링크] 유니티랑 nodejs 간단 연동 테스트 해보기  (0) 2019.03.08
[링크] iOSPlugin Sample  (0) 2019.01.29
[펌] Unity Excel Importer  (0) 2019.01.03
[링크] Emoji_Extension  (0) 2018.06.07
Posted by blueasa
, |
윈도우10 설정 ms-settings 명령어 활용하기

Windows10에서는 기존의 제어판 외에도 새로운 설정 응용 프로그램을 제공하고 있습니다. 윈도우 10의 설정 응용 프로그램은 많은 페이지로 구성되어 있으며, 이전의 클래식 제어판의 설정 기능을 그대로 활용 가능합니다.

이 설정 프로그램은 거의 모든 설정 항목에 바로 접근할 수 있는 자신만의 URL이 존재합니다. 설정 프로그램에서 특정 기능을 바로 활용하고 싶은데, 접근 루트가 복잡하거나 어느 메뉴에 있는지 모른다면 이 URL에 유용할 수 있습니다.

이번 포스팅에서는 Windows10의 설정 응용프로그램의 기능들을 바로 활용할 수 있는 URL 주소를 소개해 드리도록 하겠습니다. 이 명령어들은 윈도우 10 버전 1704 크리에이터 업데이트에서 활용 가능한 명령어 목록입니다.











윈도우10 설정 ms-settings 명령어 활용하기
윈도우10 설정 ms-settings 명령어 활용하기

예시로 색상 설정을 사용하고 싶다면, 실행창 또는 파일탐색기에 아래의 명령어를 실행해 줍니다.

ms-settings:colors

위의 명령어를 실행시키면 예시처럼 바로 색상 설정을 활용 가능합니다.

아래부터는 Windows 10 Creators Update의 ms-settings 명령 목록입니다.

[홈]
설정 메인 : ms-setting:

[시스템]
디스플레이 : ms-settings:display
알림 및 작업 : ms-settings:notifications
전원 및 절전 : ms-settings:powersleep
배터리 : ms-settings:batterysaver
앱별 배터리 사용량 : ms-settings:batterysaver-usagedetails
저장 공간 : ms-settings:storagesense
태블릿 모드 : ms-settings:tabletmode
멀티태스킹 : ms-settings:multitasking
이 PC에 대한 표시 : ms-settings:project
디바이스 간 환경 : ms-settings:crossdevice
정보 : ms-settings:about

[장치]
블루투스 및 기타 디바이스 : ms-settings:bluetooth
프린터 및 스캐너 : ms-settings:printers
마우스 : ms-settings:mousetouchpad
터치 패드 : ms-settings:devices-touchpad
펜 및 윈도우 잉크 : ms-settings:pen
자동 실행 : ms-settings:autoplay
USB : ms-settings:usb

[네트워크 및 인터넷]
상태 : ms-settings:network-status
와이파이 : ms-settings:network-wifi
이더넷 : ms-settings:network-ethernet
전화 접속 : ms-settings:network-dialup
VPN : ms-settings:network-vpn
비행기 모드 : ms-settings:network-airplanemode
모바일 핫스팟 : ms-settings:network-mobilehotspot
데이터 사용량 : ms-settings:datausage
프록시 : ms-settings:network-proxy

[개인 설정]
배경 : ms-settings:personalization-background
색 : ms-settings:colors
잠금 화면 : ms-settings:lockscreen
테마 : ms-settings:themes
시작 : ms-settings:personalization-start
작업 표시줄 : ms-settings:taskbar

[앱]
앱 및 기능 : ms-settings:appsfeatures
기본 앱 : ms-settings:defaultapps
오프라인 지도 : ms-settings:maps
웹 사이트용 앱 : ms-settings:appsforwebsites

[계정]
사용자 정보 : ms-settings:yourinfo
메일 및 앱 계정 : ms-settings:emailandaccounts
로그인 옵션 : ms-settings:signinoptions
회사 또는 학교 액세스 : ms-settings:workplace
다른 사용자 : ms-settings:otherusers
설정 동기화 : ms-settings:sync

[시간 및 언어]
날짜 및 시간 : ms-settings:dateandtime
지역 및 언어 : ms-settings:regionlanguage
음성 : ms-settings:speech

[게임]
Game bar : ms-settings:gaming-gamebar
게임 DVR : ms-settings:gaming-gamedvr
브로드캐스팅 : ms-settings:gaming-broadcasting
게임 모드 : ms-settings:gaming-gamemode

[접근성]
내레이터 : ms-settings:easeofaccess-narrator
돋보기 : ms-settings:easeofaccess-magnifier
고대비 : ms-settings:easeofaccess-highcontrast
선택 캡션 : ms-settings:easeofaccess-closedcaptioning
키보드 : ms-settings:easeofaccess-keyboard
마우스 : ms-settings:easeofaccess-mouse
기타 옵션 : ms-settings:easeofaccess-otheroptions

[개인정보]
일반 : ms-settings:privacy
위치 : ms-settings:privacy-location
카메라 : ms-settings:privacy-webcam
마이크 : ms-settings:privacy-microphone
알림 :  ms-settings:privacy-notifications
음성, 수동 입력 및 입력 : ms-settings:privacy-speechtyping
계정 정보 : ms-settings:privacy-accountinfo
연락처 : ms-settings:privacy-contacts
일정 : ms-settings:privacy-calendar
통화 기록 : ms-settings:privacy-callhistory
메일 : ms-settings:privacy-email
작업 : ms-settings:privacy-tasks
메시지 : ms-settings:privacy-messaging
라디오 : ms-settings:privacy-radios
기타 장치 : ms-settings:privacy-customdevices
피드백 및 진단 : ms-settings:privacy-feedback
백그라운드 앱 : ms-settings:privacy-backgroundapps
앱 진단 : ms-settings:privacy-appdiagnostics

[업데이트 및 복구]
Windows 업데이트 : ms-settings:windowsupdate
업데이트 확인 : ms-settings:windowsupdate-action
업데이트 기록 : ms-settings:windowsupdate-history
다시 시작 옵션 : ms-settings:windowsupdate-restartoptions
고급 옵션 : ms-settings:windowsupdate-options
Windows Defender : ms-settings:windowsdefender
백업 : ms-settings:backup
문제해결 : ms-settings:troubleshoot
복구 : ms-settings:recovery
정품 인증 : ms-settings:activation
내 장치 찾기 : ms-settings:findmydevice
개발자용 : ms-settings:developers
Windows 내부자 프로그램 : ms-settings:windowsinsider

[혼합 현실]
혼합 현실 : ms-settings:holographic
오디오 및 음성 : ms-settings:holographic-audio


반응형
Posted by blueasa
, |