사실 이 부분에 대한 글은 외국 사이트들에 많이 소개 되어 있다.
그러나, 정작 사용하려 하면 헷갈리게 구성되어 있어 이기회에 정리하도록 한다.

이전에 사용해 왔고 계속 진행해온 방법이 아래와 같은 방법이다.


<a href="javascript:" onclick="IMNImageOnClick();return false;" class="ms-imnlink">

<img title="" alt="No presence information" name="imnmark" border="0" valign="middle" height="12" width="12" src="/_layouts/images/blank.gif" sip="administrator@trainsbydave.com" id="imn0,type=smtp" >

</a>


즉 저 내용 중 SIP 라는 항목에 실제 OC 에 필요한 SIP를 넣어서 처리하곤 했다.

그런데, 간혹 위와 같이 표기하면 Presence 정보가 제대로 표시되지 않거나(SIP가 잘못된 것 처럼 아예 표시 조차 안되는 경우), 2개 씩 나오는 경우가 있다.

이에 MOSS에서 제공하는 스크립트를 가만히 뜯어 보았다. MOSS에서 제공하는 자바스크립트는 두가지 인데, 하나는 /_layouts/{LCID_CODE}/init.js 고 다른 하나는 /_layouts/{LCID_CODE}/ows.js 이다. ( LCID_CODE란 언어별 코드로 한국어면 1043 일 것이다. )

그 자바스크립트를 가만히 보게 되면 위와 같은 형태의 코로는 도무지 제대로 찾지 못하는 구조일 수 밖에 없다. ( 도리어 표시되는게 무척이나 신기한 구조다. )

예전 WSS v2 에서는 아래와 같이 구성되어 있었다.

<img border="0" height="12" width="12" src="http://portal.blackbladesystems.com/_layouts/images/blank.gif" onload="IMNRC('erosenfeld@blackbladesystems.com')" id="imn0" >

그래서 해당 Img가 Load될때 IMNRC라는 자바스크립트가 실행되면서 동작했는데, WSS v3 부터는 ProcessImn() 이라는 함수를 부르면 알아서 찾아 처리하는 것이다.

아무것도 없는데 알아서 처리할리는 없고, 실제 자바스크립트에서 찾는 방법을 간단하게 서술하면 아래와 같다.

1. name="imnmark" 라는 이름을 가진 element를 모두 검색한다.

2. 검색한 element가 span이라고 가정하고, OC의 active X에 이벤트를 연결한다.

3. 이벤트에서는 active X의 presence가 변경될 때 마다, 해당하는 이미지로 변경할 수 있도록한다. 이 때 이미지 id는 span에서 제공한다.

혹시 이 Presence 정보에 골머리를 싸아보신 분은 헉.... 이라는 한마디를 할 것이다. 저 1,3 번이 바로 OC Presence 정보의 함정인 것이였다.

먼저 아래와 같은 구조가 되어야 한다는 것이다.

<span id="{고유ID-1}" name="imnmark" >
  <img id="{고유ID-1}" src="blank.gif" >
</span>

서두에 전달드렸던 태그와는 전혀 생뚱맞지 않은가?

즉 <a> <img> </a> 형태가 아닌 <span><img></span>이되어야 한다는 것이다.

그런데, 여기서 잠깐!. 저 ID가 무척 웃기는 구조이다. 정말이지 고유 ID가 되어야 정확한 이미지 변경이 가능하다.만일 모든 Presence 정보의 ID를 맨 위의 코드 처럼 id="imn0,type=smtp"  라고 쓰면 한개의 이미지만 그럴싸하게 나오고 나머지에서는 제대로 표시도 안된다.

그렇다면, 저 ID는 어떻게 뽑을까?

물론 한 페이지에 이 Presence 정보를 뽑는 곳이 딱 한개의 웹파트에서 모두 표시된다면 문제가 없다. 그 안에서 int nIndex = 0; 한다음에 뺑뺑이 돌면서 ID를 만들면 된다. id="imn0,type=smtp" , id="imn1,type=smtp", id="imn2,type=smtp", id="imn3,type=smtp"... 이런 식으로 표시만 되면 된다.

그런데.. 만일 멀티 웹파트 인경우에는 어떻게 해야 할까?

사실 이것 때문에 조금 고민했다.  웹 구성요소(웹 컨트롤, 웹 파트 등)에서 모두 공유해서 쓸만한 변수라는게 있을까? 웹 컨트롤 내에 백개의 변수를 정해줘바야 다른 웹 컨트롤이나 웹 파트에서 접근도 못할 뿐더러, 이미 접근할 때에는 그 객체는 Render 하고 끝났을 테니깐...

그러다가, 이렇게 생각을 조금 다르게 바라보자,  웹페이지에서도 나름대로 공용 변수를 하나 세울 수 있었다.

바로 HttpContext.Current.Cache라는 것이였다.

즉 저 안에는 Key 값을 정해준뒤, object 형태의 값을 넣을 수 있는데, 바로 그 점에 착안한 것이다.

즉 Presence 정보를 표시하는 모든 웹 구성요소들은  아래와 같은 캐쉬를 꼭 읽도록 한다.

object val = HttpContext.Current.Cache["PRESENCE_COUNT"];

만일 val이 null 이라면 새로 값을 넣고, 그렇지 않으면 그 값을 사용한다.

presence 정보를 쭉 나열한 뒤, 전체 인덱스가 변했다면, 이젠 그 값을 Set 해준다. 이 때 만료시간은 2~3초로 잡아주면 끝날 것이다.

아래의 코드를 참고하도록 한다.

static public string GetPresenceInfoHtml(string sSipAddress)
{
      string CacheName = CACHE_PRESENCE_COUNT_PREFIX +   UserData.GetCurrentUserId();
       int nCount = 0;
       object val = CacheHelper.GetCache(CacheName);
       if (val != null)
       {
            nCount = (int)val;
            nCount++;
        }

        string sId = "imn" + nCount.ToString() + ",type=smtp";
        StringBuilder sbContent = new StringBuilder();
        sbContent.Append("<span name=\"imnmark\" ShowOfflinePawn=\"true\" id=\"" + sId + "\" sip=\"" + sSipAddress + "\">");
         sbContent.Append("<img border=\"0\" id=\"" + sId + "\" valign=\"middle\" height=\"12\" width=\"12\" src=\"/_layouts/images/blank.gif\" onload=\"IMNRC('" + sSipAddress + "');\" sipaddr=\"" + sSipAddress + "\" />");
         sbContent.Append("</span>");
        CacheHelper.SetCache(CacheName, DateTime.Now.AddSeconds(5), nCount);

         return sbContent.ToString();
}


( 위의 코드 중 CacheHelper.SetCache와 GetCache는 신경 쓰지 않도록 한다. HttpContext.Current.Cache를 쉽게 사용할 수 있도록 구성한 함수 들이다. )


* 주의! : Presence를 표시하는 Html 부분을 AJAX 기법으로 동적으로 추가되도록 구성하지는 말자. <div> 안에 innerHTML 같은 것으로 해당 부분의 Html을 넣거나 빼게 되면 그 안의 값은 getElementById 혹은 getElementByName 등의 함수로 찾지 못하는 경우가 발생한다. 가급적 HTML은 미리 인쇄될 수 있도록 구성해야 한다.

728x90

+ Recent posts