BLOG main image
분류 전체보기 (239)
Rails (65)
Ruby (34)
이야기 (40)
스토리큐 (61)
그 밖에.. (30)
C# (6)
작은아이의 생각
agiletalk's me2DAY
[rails] Growl4Rails
美소년 ㅇㅅㅇ씨의 一日
마사키군의 생각
ayukawa's me2DAY
작은아이의 생각
agiletalk's me2DAY
[Google App Engine] 나의 첫번..
머드초보의 블로그
54,086 Visitors up to today!
Today 10 hit, Yesterday 42 hit

 SUBSCRIBE

'2009/04'에 해당되는 글 16건
2009/04/26 22:47

상업성 짙은 책 제목. 또 하나의 자기 개발서. 부정적으로 보면 특별할 것 없는 이야기, 많은 책에서 이미 다룬 이야기라고 생각할 수도 있습니다. 긍정적으로 보면 쉽습니다. 저자 자신의 이야기들을 과장 없이 예로 들어서 거부감 없이 읽혀집니다.

마음에 들었던 부분, 읽으면서 가졌던 생각들을 조금 적어 봅니다.

목표를 가져야 합니다. 비전을 가져야 합니다. 성공을 위해서 그것보다 중요한 것은 없습니다.

직장생활을 충실히 하는 것도 성공을 위한 좋은 전략입니다. 사원으로 시작해 기업의 임원까지 가는 전략은 안정적이고 충분한 보상을 받을 수 있습니다. 우선 월급을 받기 때문에 내가 짊어져야 하는 위험이 적습니다. 적어도 끼니 걱정은 하지 않아도 됩니다. 업무를 수행하면서 성취감을 느낄 수 있으며, 임원, 사장 같은 직책까지 오르게 되면 충분한 돈도 벌 수 있습니다. 업무의 선택이 자유롭지 않다는 점과, 임원이 되기까지의 경쟁이 심하다는 문제가 있지만, 어느 일이나 이 정도의 어려움은 있습니다. 자신이 좋아하는 일을 하고 있다면, 그 일을 하고 있는 기업에서 승부를 거는 것도 훌륭한 전략입니다.

일 자체를 즐길 수 있어야 합니다. 이 관점에서 봤을 때 나는 좋아하는 프로그래밍을 하고 있고, 그것을 원하는 만큼 배울 수 있는 환경도 가지고 있고, 좋아하는 사람들과 일하고 있기 때문에 행운입니다. 프로그래밍에 대한 미래 수요는 계속 늘어날 것이고, 지식이 쌓이게 될 수록 경쟁력도 높아질 것입니다. 이 일에 집중해도 좋습니다.

저자는 컨설팅 일을 하고 있습니다. 효율적인 생활, 생산적인 삶을 갖기 위해 컨설팅을 받아보는 것도 좋겠다는 생각을 해 봅니다. 그들에게 지불한 만큼 얻을 수 있을 것 같다는 생각이 듭니다.

다른 사람의 이야기에 관심을 가져야 합니다. 그들의 이야기를 듣고, 공감해야 합니다. 우선 그들의 입장에서 공감한 후, 내 생각을 만들어도 늦지 않습니다.

하지만 어렵다.

머리로는 이해가 되고, 읽을 때는 ‘그래, 이렇게 살아야겠다’ 라는 생각을 하지만, 정말로 그렇게 사는 것은 또 다른 일입니다. 왜일까요? 
좋은 레시피가 있다면 어느 정도 수준의 요리를 만드는 것은 그리 어렵지 않습니다. 반면에 아무리 좋은 수영하는 법에 대한 이론 수업을 듣는다 해도 금방 수영을 할 수는 없습니다. 어쩌면 이런 이야기들은 수영 수업처럼 생활에 적용하기 위해서는 부단한 노력이 필요한 것일 지도 모릅니다. 이렇게 생각해 봤을 때, 보통 자기 개발서들은 지나치게 방대한 내용을 다루고 있습니다. 한가지 주제를 생활에 적용할 수 있도록 자세히 다루는 것이 어떨까 하는 생각을 해봅니다. 어차피 이론으로 해결할 수 없는 일일까요?
실체가 없는 주제이기 때문에 내가 잘하고 있는 것인지 측정하기 어렵습니다.
단기적으로 눈으로 볼 수 있는 성과를 기대하기 어렵습니다. 목표와 비전을 만든다고 해도 당장 어떤 것도 바뀌지 않습니다. 목표를 달성하기 위한 오랜 시간 동안의 여정이 필요합니다. 쉽지 않습니다.
어떤 때는 마음에 드는 두 가지 이야기가 서로 반대되는 방향을 향하고 있습니다. 적게 일하고 생활에 여유를 갖도록 하라는 것과, 항상 바쁘게 살도록 하라는 이야기. 절충되는 점을 찾을 때까지는 혼란입니다.

이거 하나면 돼. 라고 할 수 있는 마법 같은 원칙이 어디 없을까요? 이 말을 가능한 한 많이 생각하는 것을 어떨까요?

성공을 원한다면 이미 성공한 사람처럼 행동하라.

'이야기' 카테고리의 다른 글

사진빨 받은 진이  (0) 2009/05/13
습관의 힘  (0) 2009/05/10
직장인의 운명은 30대에 결정된다.  (0) 2009/04/26
지난 주 멋진 말들  (0) 2009/04/15
수제 쿠키  (0) 2009/04/10
프랑스 - 에펠탑  (0) 2009/04/06
2009/04/26 22:33

C# 코드를 읽다가 int? 라는 표현을 봤다. 독특한 표현이다. 짐작도 잘 안 될 만큼. 무엇일까?

nullable type

nullable type은 null로 할당할 수 있는 data type을 말한다. System.Nullable<int>와 같은 식으로 선언할 수 있고, 더 짧은 표현으로 int? 로 쓸 수 있다.

  1. int? num = null;

int 형으로 선언된 변수에는 null을 사용할 수 없다. 그러나 int? 로 선언한 변수에는 null을 할당할 수 있다.
어색하고 직관적이지는 않다.

nullable type으로 선언된 변수(객체)는 HasValue 멤버를 갖는다.

  1. int? x = 30;
  2. if (x.HasValue)
  3.    Console.WriteLine(x.Value);

default값 주기

한발 더 나아가 어떤 변수가 null일 때 기본값을 주도록 할 수 있는 방법 중 하나는 다음과 같이 3항 연산자를 사용하는 것이다.

  1. num = num? 0 : num;

위 표현을 ??를 이용해서 더 간결하게 할 수도 있다.

  1. num = num ?? 0
2009/04/25 20:51

string을 int로 변환하기

간단하게 Parse 메소드를 사용할 수 있다.

  1. short.Parse("13");
    double.Parse(“3.4”);
    int.Parse(“4”);

hex string을 변환하고 싶다면

  1. int.Parse("0a", System.Globalization.NumberStyles.HexNumber)
Byte를 다른 데이터형으로 변환하기

byte array를 string으로변환하기

  1. var asciiEncoding = new ASCIIEncoding(); 
    string str = asciiEncoding.GetString(bytes);
    // 혹은
    Encoding.ASCII.GetString(bytes);

byte array를 int로 변환하기

  1. byte[] bytes = { 0, 0, 0, 25 };
    // If the system architecture is little-endian (that is, little end first),
    // reverse the byte array.
    if (BitConverter.IsLittleEndian)
      Array.Reverse(bytes);
    int i = BitConverter.ToInt32(bytes, 0);
    Console.WriteLine("int: {0}", i);
    // Output: int: 25

BitConverter.IsLittleEdian 을 이용해서 시스템이 사용하는 edian에 대해 알 수 있다. 참고로 x86계열은 little edian, 네트웍 프로토콜은 주로 big edian 사용한다.

byte array를 보기 좋은 hex string으로 변환하기

  1. BitConverter.ToString(bytes)
    => 00-00-01-0E
다른 데이터 형을 Byte로 변환하기

string을 ascii byte array로 변환하기

  1. var encoding = new ASCIIEncoding();
    var bytes = encoding.GetBytes(value);
    // 혹은
    System.Text.Encoding.ASCII.GetBytes(message);

double, int, short 등 숫자를 byte array로 변환하기

  1. double msec = 10000;
    BitConverter.GetBytes(msec);

역시 edian에 대한 고려를 해주어야 한다. little edian을 사용하는 시스템에서는 다음과 같은 결과가 나온다.

  1. var intVal = 10000;
    var bytes = BitConverter.GetBytes(intVal);
    Console.WriteLine(BitConverter.ToString(bytes));
    => 10-27-00-00
참조

http://msdn.microsoft.com/en-us/library/bb384066.aspx

2009/04/20 23:59

요즘 주로하는 업무는 C#을 이용합니다. 익숙함을 벗어나는 것에는 스트레스가 따르지만, 새로운 것을 배운다는 것은 즐거운 일이기도 합니다. 익숙해진 ruby에 비하면 불편하고, 복잡하게 느껴지기도 하지만, 그런 불평들은 아마도 무지함에 대한 다른 표현들이겠지요.

C#에 대해 조금씩 알아나가게 되면서 느끼는 것은 언어가 서로 서로 닮아간다는 것입니다. C#은 스크립트 언어가 아님에도 불구하고 스크립트 언어만큼 유연성을 주는 기능들이 추가되어 가고 있습니다. 3.0에서는 lamda 기능이 추가되었고 닫혀있는 클래스의 method 확장도 되며, C# 4.0 에서는 dynamic typing도 된다고 합니다.

ruby로 일하면서 가장 좋았던 것 중 하나는 rspec이었습니다. C#으로 테스트 코드를 작성하려면 어떤 것들이 필요할까? 라는 생각으로 조사를 좀 해 봤습니다. 테스트에 관련된 라이브러리들이 생각보다 많아서 놀라기도 하고, 당혹스럽기도 했습니다. 찾고자 하는 것은 가장 멋진 test framework과 가장 멋진 mocking framework이었습니다. 독보적은 지위를 갖는 것은 없었지만, 마음에 드는 것을 결정할 수는 있었습니다. xUnit.netmoq입니다.

덤으로 ReShaper 같은 훌륭한 비쥬얼 스튜디오 툴도 있다는 것도 알게 되었습니다. 아직 제대로 사용해 본 것은 아니지만, TDD를 하기에 충분히 잘 갖추어진 환경이라는 생각이 듭니다.

2009/04/15 12:42

능력이 사람을 평가하는데 있어 가장 중요한 요소가 될 수는 없습니다. 그 능력이 우리를 등지게 되면 그것만큼 신경쓰이는 일도 없습니다.

신의가 없으면 아무리 뛰어나도 쓸모가 없다. – 앤드류 카네기

실용적이지 않은 지식이라 해도 그 지식이 쓸모없는 것은 아닙니다. 인간을 행복하게 만들 수 있다는 측면에서 볼 때, 금전적일 이익을 주는 지식 못지않게 철학적인 이야기도  충분한 가치가 있습니다. 커피의 기원이 어떻게 되고, 초컬릿은 무엇으로 만들어진다는 지식이 커피와 초컬릿의 즐거움을 더욱 향상시킨다면 이 역시 귀중한 지식입니다.

진귀한 지식은 불쾌한 일을 덜 불쾌하게 만들 뿐 아니라, 즐거운 일을 더 즐겁게 만들어 준다. – 버트런트 러셀

행복이 무엇인지 모릅니다. 모르는 것을 기대할 수는 없는 노릇입니다. 그런 막연함 보다는 ‘웃음’과 같은 구체적인 것이 더 낫겠습니다.

내게 행복을 빌어주지 말라. 나는 행복을 기대하지 않는다. 행복을 빌어줄 단계는 지났다. 내게 용기와 힘과 유머감각을 빌어 달라. 내게는 그러한 것이 필요할 것이다. – 앤 모로 린드버그

비판을 멈추어야 합니다.

비판의 즐거움은 우리에게서 아주 멋진 것들에 의한 감동의 즐거움을 빼앗아간다. – 장 드 라브뤼에르

'이야기' 카테고리의 다른 글

습관의 힘  (0) 2009/05/10
직장인의 운명은 30대에 결정된다.  (0) 2009/04/26
지난 주 멋진 말들  (0) 2009/04/15
수제 쿠키  (0) 2009/04/10
프랑스 - 에펠탑  (0) 2009/04/06
제 7회 LIG 코리아 오픈 마라톤 대회 참가 후기  (0) 2009/04/05
2009/04/14 22:33

MySpace는 소셜 네트워킹 사이트다. 그만큼 사용자와 사용자 사이의 의사소통이 중요하다. 좋은 것이 있으면 친구와 공유하고, 재미난 것이 있으면 같이 즐기면서 서로 관계가 쌓이게 된다. 애플리케이션에서 친구에게 메시지를 보내고, 애플리케이션에 초대할 수 있다면 사용자들 사이에 관계를 만들어 나가는데 도움을 줄 것이다. 이번 글에서는 사용자에게 메시지를 보내는 방법에 대해 알아보자.

사용자에게 메시지 보내기

친구에게 보내는 메시지는 requestSendMessage를 통해서 이루어진다. 그 프로토타입은 다음과 같다.

  1. <static> requestSendMessage(recipients, message, opt_callback, opt_params)

recipients는 String으로 메시지를 받는 사람의 id 혹은 id의 array이다. myspace에서는 현재 array에 대해서는 지원하지 않고 있다. opt_callback은 메시지를 보낸 후 불려지는 콜백 함수이다. opt_params는 myspace에서는 현재 지원하지 않는다.
message는 opensocial.Message 로 보내려는 메시지이다. opensocial.newMessage 함수를 통해 만들 수 있다.

  1. <static> opensocial.Message newMessage(body, opt_params)

body는 String으로 보내려는 메시지이다. opt_params 에 TYPE을 지정해서 이 메시지가 어디로 이동할 지 결정할 수 있다.

  • EMAIL : 현재 지원 안함.
  • NOTIFICATION : 불레틴보드에 들어감
  • PRIVATE_MESSAGE : inbox에 들어감.
  • PUBLIC_MESSAGE : comment에 들어감.

다음은 친구에게 메시지를 보내는 한 예이다.

  1. var params = {};
  2. params[opensocial.Message.Field.TITLE] = "This slide is awesome!";
  3. params[opensocial.Message.Field.TYPE] = opensocial.Message.Type.PUBLIC_MESSAGE;
  4. var body = "<h4> Come and See me! </h4>";
  5. var message = opensocial.newMessage(body, params);
  6. opensocial.requestSendMessage(FRIEND_ID, message, function(resp) {
  7.   console.debug(“success”);
  8. });

실행하면 다음과 같은 식으로 MySpace의 메시지 보내기 템플릿을 이용해 메시지를 보낼 수 있다.

1

사용자를 애플리케이션에 초대하기

사용자를 초대할 때는 opensocial.requestShareApp 함수를 이용한다. 프로토타입은 다음과 같다.

  1. <static> requestShareApp(recipients, reason, opt_callback, opt_params)

reason은 opensocial.Message이다. requestSendMessage와 거의 비슷하다.

  1. var body ="[sender] would like you to install this really super application [app]."
  2. var message = opensocial.newMessage(body);
  3. opensocial.requestShareApp(friend_id, message, function() {
  4.   console.debug(“success”)
  5. });

requestSendMessage와 다른 점은 body에 [sender], [app] 같은 예약어를 사용할 수 있다. 짐작하는 그대로 [sender]는 초대하는 사람, [recipient]는 초대를 받는 사람, [app]는 초대하려는 애플리케이션이다. MySpace 의 App Invite 문서를 보면 더 자세한 설명을 얻을 수 있다.

참고로 requestSendMessage, requestShareApp는 0.8에 생긴 API이다. 0.7 에서는 PostTo를 이용했다고 한다.

마이스페이스에 메시지 보내는 것에 대한 데모 애플리케이션이 있으니 실행해 보는 것도 좋겠다.

2009/04/10 00:40

이번에 소개할 내용은 두 가지다. 하나는 프로파일 뷰에서 캔버스 뷰로 이동하는 방법에 대한 것이고, 다른 하나는 캔바스 뷰를 보여줄 때 애플리케이션에 파라미터를 전하는 방법이다.

프로파일 뷰에서 캔버스 뷰로 이동

프로파일 뷰의 이미지를 클릭하면 캔버스 뷰로 이동하고 싶은 경우가 있다. 가장 먼저 생각할 수 있는 손쉬운 방법은 <a> 태그를 이용하는 것이다. 애플리케이션 캔버스 뷰의 URL은 다음과 같은 식이다.

  1. http://profile.myspace.com/Modules/Applications/Pages/Canvas.aspx?appId=132996

이 방법은 잘 동작하는 듯이 보이지만, 문제가 있다. 이동한 캔버스뷰에서 뒤로가기(back) 버튼을 누르면 프로파일 뷰로 이동하는 것이 아니라 다시 캔버스 뷰가 보인다. 프로파일 뷰가 frame안에 있기 때문에 이와 같이 정상적인 방법은 잘 통하지 않는다.

다행히 opensocial API 중 gadgets.views 를 보면 이와 같은 경우에 사용해야할 API들이 있다. 프로파일 뷰로 이동하는 요청은 다음과 같다.

  1. var surfaces = gadgets.views.getSupportedViews();
  2. var surfaceRef = surfaces['CANVAS'];
  3. var params = {box_id : box.id};
  4. gadgets.views.requestNavigateTo(surfaceRef, params);

getSupportedViews() 는 이 애플리케이션이 지원하고 있는 뷰들의 목록을 리턴한다.
requestNavigateTo() 를 이용해서 원하는 뷰로 이동할 것을 요청할 수 있다. 이 방법을 이용하면 뒤로가기 버튼도 잘 동작한다. 함수를 호출할 때 파라미터도 넣을 수 있다. 파라미터를 지정하면 다음과 같은 식의 URL로 이동한다.

  1. http://profile.myspace.com/Modules/Applications/Pages/Canvas.aspx?appId=132996&friendId=370643088&appParams={%22box_id%22%3A6716}

파라미터가 appParams 안에 (“box_id”:6716} 이런 식으로 들어 있다.

캔버스 뷰에서 파라미터를 받기

위와 같은 URL로 캔버스 뷰에게 전해진 파라미터를 캔버스 뷰에서는 다음과 같은 식으로 가져올 수 있다.

  1. if(gadgets.views.getParams().appParams) {
  2.   var boxid = gadgets.views.getParams().appParams.box_id
  3. }

getParams() 함수를 통해 애플리케이션이 로딩될 때 파라미터들을 가져올 수 있다. 이 함수는 유용한 정보를 많이 가지고 있는데, 그 중 VIEWER, OWNER 의 id도 있다.

  1. gadgets.views.getParams().appid
  2. gadgets.views.getParams().viewerId
  3. gadgets.views.getParams().ownerId
2009/04/10 00:04

작년에 회사에서 추석선물로 오븐을 받아서 동생에게 주었습니다. 좀 늦은 감이 있지만, 동생은 그 오븐으로 쿠키를 만들어서 회사에 보냈습니다. 덕분에 화창한 오후에 좋아하는 사람들과 쿠키를 먹으며 좋은 시간을 보낼 수 있었습니다.

맛이 꽤 좋았습니다. 정성이 담겨있기 때문이겠지요? ^^

동생에게 고맙고, 엔블링크와 동료들에게도 고마운 마음입니다.

'이야기' 카테고리의 다른 글

직장인의 운명은 30대에 결정된다.  (0) 2009/04/26
지난 주 멋진 말들  (0) 2009/04/15
수제 쿠키  (0) 2009/04/10
프랑스 - 에펠탑  (0) 2009/04/06
제 7회 LIG 코리아 오픈 마라톤 대회 참가 후기  (0) 2009/04/05
백만불짜리 습관  (0) 2009/04/01
2009/04/07 14:56

 RED5 설치와 데모에 이어 jRuby로 RED5 애플리케이션을 만들어 보자. 목표는 oflaDemo 앱을 jRuby로 빌드해서 성공적으로 실행해 보는 것이다. 그럼으로써 RED5 애플리케이션에 대한 이해의 폭을 늘려보자.
내가 java 웹 애플리케이션에 대한 지식이 없기 때문에 내용이 지루할 수도 있다. 그러나 나는 내 기준으로 새로운 내용을 쓸 수 밖에 없다.

준비물은 다음과 같다. JAVA, NetBeans, RED5, oflaDemo 소스. NetBeans를 설치하면 ANT, jRuby 가 덩달아 같이 설치된다.

애플리케이션의 생성

디렉토리를 하나 생성한 후  jrubyDemo 라고 이름을 지어준다. 그 밑에 oflaDemo 소스의 src, www 디렉토리를 복사한다. war 밑의  oflaDemo-web.xml 파일도 src 디렉토리에 복사한다.
NetBeans를 실행시켜서 java Web 의 Web Free-Form Application 프로젝트를 생성한다. project 의 디렉토리를 jrubyDemo로 선택한다. java sources classpath에 RED5_HOME/red5.jar를 추가시켜 주면 NetBeans에서 소스를 보기 편해진다.
필요 없는 파일들인 src 디렉토리 밑의 oflaDemo-web.xml, *.js, *.py, *.groovy, Application.java, DemoService.java를 지운다. www 밑의 logertest.jsp 와 streams도 필요없다. ivy.xml, ivysettings.xml 파일도 지운다.

3

소스의 수정

src 밑의 logback-oflaDemo.xml 파일을 logback-jrubyDemo.xml로 변경한다. 이 파일이 logger에 대한 설정 파일이다. 파일을 열어서 oflaDemo를 jrubyDemo로 변경한다.

WEB-INF 밑의 web.xml 파일을 열어서 oflaDemo를 jrubyDemo로 변경시킨다. red5-web.properties 파일에서도 contextPath를 /jrubyDemo로 변경시킨다. contextPath를 지정함으로써 /jrubyDemo로 오는 요청들을 이 애플리케이션이 처리하게 된다. red5-web.xml 파일은 java용으로 web.handler와 demoService.service가 설정돼 있다. 다음과 같이 이것들을 주석으로 막고, 루비용 설정의 주석을 풀자.

  1. <bean id="web.handler" class="org.springframework.scripting.jruby.JRubyScriptFactory">
  2.   <constructor-arg index="0" value="classpath:applications/main.rb"/>
  3.   <constructor-arg index="1">
  4.     <list>
  5.       <value>org.red5.server.api.IScopeHandler</value>
  6.       <value>org.red5.server.adapter.IApplication</value>
  7.     </list>
  8.   </constructor-arg>
  9. </bean>
  10. <bean id="demoService.service" class="org.springframework.scripting.jruby.JRubyScriptFactory">
  11.   <constructor-arg index="0" value="classpath:applications/demoservice.rb"/>
  12.   <constructor-arg index="1">
  13.     <list>
  14.       <value>org.red5.demos.jrubyDemo.IDemoService</value>
  15.     </list>
  16.   </constructor-arg>
  17. </bean> 
  18. <!--
  19. <bean id="web.handler" class="org.red5.demos.oflaDemo.Application" />
  20. <bean id="demoService.service" class="org.red5.demos.oflaDemo.DemoService" />
  21. -->

demoService.service에서는 oflaDemo를 jrubyDemo로 변경해 주어야 한다. 정확한 지식 없이 내용을 대강 이해해 보자면, 들어오는 요청이 루비 파일과 연결되도록 설정해 주는 듯 싶다.

org/red5/demos/oflaDemo 의 디렉토리를 org/red5/demos/jrubyDemo 로 변경하자. NetBeans에서 변경한다면 java 파일들의 리팩토링도 알아서 해 준다. 그것이 아니라면, java 파일들을 열어서 oflaDemo를 jrubyDemo로 변경하자.

build 및 실행

build.xml 파일을 다음과 같이 수정한다.

  1. <?xml version="1.0"?>
  2. <project name="jrubyDemo" basedir="." default="build">
  3. <!-- Project properties –>
  4.   <property environment="env"/>
  5.   <property file="build.properties"/>
  6.   <property name="src.dir" value="src"/>
  7.   <property name="classes.dir" value="www/WEB-INF/classes"/>
  8.   <property name="lib.dir" value="www/WEB-INF/lib"/>
  9.   <property name="target.jar" value="jrubyDemo.jar"/>
  10. <!-- End Project properties –>
  11. <!-- webapps Classpath –>
  12.   <path id="project.classpath">
  13.     <fileset dir="${red5.root}/lib"/>
  14.     <pathelement location="${red5.root}/red5.jar"/>
  15.     <pathelement location="${red5.root}/lib/red5.jar"/>
  16.         <!-- project specific libs –>
  17.     <fileset dir="${lib.dir}"/>
  18.   </path>
  19. <!-- End webapps Classpath –>
  20. <!-- Clean webapp –>
  21.   <target name="clean" description="Cleans WEBAPP dir">
  22.     <echo message="Deleting the classes and lib directories...." />
  23.     <delete dir="${classes.dir}"/>
  24.     <delete dir="${lib.dir}"/>
  25.   </target>
  26. <!-- End Clean webapp –>
  27. <!-- Prepare webapp –>
  28.   <target name="prepare" depends="clean">
  29.     <echo message="Creating the classes and lib directories...." />
  30.     <mkdir dir="${lib.dir}"/>
  31.     <mkdir dir="${classes.dir}"/>
  32.     <mkdir dir="${classes.dir}/applications"/>
  33.   </target>
  34. <!-- End Prepare webapp –>
  35.   <target name="compile" depends="prepare">
  36.     <echo message="Compiling application sources...." />
  37.     <javac
  38.             sourcepath=""
  39.             srcdir="${src.dir}"
  40.             destdir="${classes.dir}"
  41.             classpathref="project.classpath"
  42.             optimize="true"
  43.             verbose="false"
  44.             fork="true"
  45.             nowarn="true"
  46.             deprecation="false"
  47.             debug="true"
  48.             compiler="modern"
  49.             source="1.6"
  50.             target="1.6"
  51.         />
  52.     <echo message="Copying scripting sources..." />
  53.     <copy todir="${classes.dir}/applications">
  54.       <fileset dir="${src.dir}/applications"/>
  55.     </copy>
  56.     <copy todir="${classes.dir}" file="${src.dir}/logback-jrubyDemo.xml" overwrite="true"/>
  57.     <copy todir="${lib.dir}">
  58.       <fileset dir="${red5.root}/lib">
  59.         <include name="slf4j-api-1.5.6.jar"/>
  60.         <include name="logback-core-0.9.14.jar"/>
  61.         <include name="logback-classic-0.9.14.jar"/>
  62.       </fileset>
  63.     </copy>
  64.   </target>
  65.   <!-- Build webapp –>
  66.   <target name="build" depends="jar">
  67.     <echo message="Building application... " />
  68.     <copy todir="${red5.root}/webapps/jrubyDemo">
  69.       <fileset dir="www">
  70.       </fileset>
  71.     </copy>
  72.   </target>
  73. <!-- End Build webapp –>
  74. <!-- Create Jar –>
  75.   <target name="jar" description="Make Archive" depends="compile">
  76.     <echo message="Creating Jar" />
  77.     <jar destfile="${lib.dir}/${target.jar}">
  78.       <fileset dir="${classes.dir}">
  79.         <include name="**"/>
  80.       </fileset>
  81.     </jar>
  82.   </target>
  83. <!-- End Create Jar –>
  84. </project>

프로젝트의 Properties를 열어서 Build and Run의 Build Project를 build로 변경한다. 이제 빌드를 해 보자. 빌드가 성공하면서 RED5_HOM/webapps 밑에 jrubyDemo가 생기는 것을 볼 수 있다. 이 디렉토리 밑에 flv 파일들이 들어 있는 streams 디렉토리를 oflaDemo로부터 복사한다.

애플리케이션을 적용시키기 위해서는 RED5 서버를 재시작해야 한다. http://localhost:5080/demos/ofla_demo.html 에 접속해서 rtmp://localhost/jrubyDemo 에 접속해 본다. 접속이 된다. 그러나 flv 파일들이 목록에 나오지는 않는다.

1

디버깅을 위해서는 서버를 콘솔에서 실행하는 것이 좋다. 서비스로 실행하고 있었다면 서비스를 중지하고 RED5_HOME 에서 red5.bat을 실행시키자. 그러면 콘솔을 통해서 puts로 출력되는 루비 메시지들을 볼 수 있다. 그리고 또 한가지, 다음 Exception이 발생한 것을 볼 수 있다.

  1. uninitialized constantRedFive::DemoServiceImpl; nested exception is org.jruby.exceptions.RaiseException

demoservice.rb 파일을 열어서 oflaDemo를 jrubyDemo로 변경한다. 그리고 module RedFive … 를 다음으로 변경한다.

  1. require 'webapps/jrubyDemo/WEB-INF/lib/jrubyDemo.jar'
  2. module RedFive
  3.   include_package "org.springframework.core.io"
  4.   include_package "org.red5.demos.jrubyDemo"
  5. end

jrubyDemo.jar 파일을 require 해 주고, DemoServiceImpl이 있는 jrubyDemo package를 포함시켜야 한다. 다시 빌드를 하고 RED5를 재시작시키자. 이제 oflaDemo와 똑같이 동작한다.

2

logger 추가

한 가지만 더 해보자. 애플리케이션의 로그는 RED5_HOME/log/jrubyDemo.log 파일에 기록된다. ruby로 이 파일에 로그가 기록될 수 있도록 해보자. main.rb를 열어서 initialize 함수에 다음을 추가한다.

  1. @log =  org.red5.logging.Red5LoggerFactory.get_logger(Application.java_class, "jrubyDemo")
  2. @log.info("hello jrubyDemo : created");

require ‘java’ 를 했기 때문에 java의 class를 org.red5.logging.Red5LoggerFactory 식으로 사용할 수 있다. 물론 include_class 를 이용해서 보다 간결한 표현을 쓸 수도 있다.
java의 class를 얻기 위해서는 java_class 메소드를 사용할 수 있다. class 메소드는 루비의 클래스를 리턴한다.
jrubyDemo는 logback-jrubyDemo.xml 에서 설정한 logger의 이름이다.

참조

jruby scripting explained
calling java from jruby

2009/04/07 14:56

fetch RED5는 RTMP(Real Time Messaging Protocol)을 이용하는 플래시 미디어 서버이다. RTMPAdobe Systems 에서 플래시와 서버 사이의 비디오, 오디오 스트리밍을 위해 고안한 프로토콜이다. 플래시로 미디어 스트리밍 서비스를 하기 위해서는 RTMP를 사용해야 하는데, adobe에서는  RTMP 서버인 FMS(Flash Medea Server)를 고가에 팔고 있다. RED5는 abobe의 FMS의 오픈소스 버전이라고 생각하면 된다. 최근에 (2009년 3월) RTMP 프로토콜이 공개되었지만, RED5가 개발될 때는 프로토콜조차 공개되지 않은 모양이다.  그 상태에서 이 정도의 제품을 만들다니, 대단한 사람들이다. 이제 그 힘을 느껴보자.

RED5 설치

현재(2009년 4월)의 최근 버전은 v0.8 RC2이다. 다운 받아서 설치하자. 설치는 매우 간단하다. 우선 JAVA가 설치되어 있어야 한다. 그리고 JAVA_HOME 환경변수를 JRE 디렉토리로 설정한다.

  1. JAVA_HOME = C:\Program Files\Java\jre6

설치가 끝난 후 바탕화면에 red5.bat 바로가기가 생기는데, 동작하지 않는다. 지워버리자. 그 대신 RED5가 설치된 디렉토리의 red5.bat을 실행해서 서버를 구동시킬 수 있다. 처음에는 이 파일을 실행해야 되지만, 재부팅 후에는 자동으로 윈도우즈 서비스로 등록된다.

혹시 실행이 안된다면 RED5_HOME 환경변수를 설정해 주자.

  1. RED5_HOME = C:\Program Files\Red5

Demo 실행해 보기

RED5 서버가 실행된 후에는 http://localhost:5080/ 으로 접속해서 데모를 볼 수 있다. 첫 화면의 동영상을 꼭 보자. 데모를 이해하는 가장 손쉬운 방법이다.

RED5_HOME\webapps가 RED5 애플리케이션들의 루트 디렉토리이다. /install에서 RED5 애플리케이션을 설치하면 이 디렉토리 밑에 애플리케이션들이 추가된다. RED5_HOME\webapps\root는 웹 페이지의 루트 디렉토리이다.

oflaDemo 애플리케이션은 RED5 서버에 위치한 flv 동영상 파일을 브라우저의 플래시 플레이어를 이용해서 볼 수 있도록 해 준다.

Shared Ball 애플리케이션은 shared object를 이용해서 두 명 이상의 사용자가 그림의 위치를 공유할 수 있음을 보여준다.

Simple Chat은 shared object를 이용해서 사용자간의 채팅 서비스를 구현했다.

좋은 점은 이처럼 다양한 데모들의 소스들이 http://red5.googlecode.com/svn/flash/trunk/http://red5.googlecode.com/svn/java/example/trunk/ 에 공개되어 있다. RED5 애플리케이션을 개발하려고 한다면 좋은 출발점이 될 것이다.

RED5 애플리케이션

위와 같이 설치를 했다면, RED5 서버는 tomcat을 서블릿 컨테이너로 사용한다. 그리고 apache-coyote를 HTTP Connector로 사용한다. red5, tomcat 에 대한 설정은 RED5_HOME\conf 에 있다. 참고로 red5.properties에 서버 환경에 관한 내용이 있다.
RED5 애플리케이션은 일반적은 java 웹 애플리케이션의 모양과 같다. java를 잘 알고 있는 개발자라면 어렵지 않을 듯 싶다. 반면에 본인은 매우 낯설다.

oflaDemo의 소스를 다운 받아서 살펴보자.
src/org/red5/demos/oflaDemo에 java의 소스들이 있다. src/applications에 보면 groovy, python, javascript 그리고 친숙한 ruby로 된 파일이 있다. jruby로도 구현을 잘 해 놓은 듯 하다. 출발이 좋다.

java 소스의 빌드는 ANT를 이용한다. RED5_HOME 환경변수를 설정하고, 애플리케이션 홈의 build.xml을 ANT를 이용해 실행하면 별 문제 없이 빌드가 될 것이다.

다음 글은 ‘jruby를 이용해서 oflaDemo를 빌드해 보기’ 이다.

prev"" #1 #2 next