2011. 9. 2. 14:45


이 글에서는 스카이프 api를 이용하여 채팅,전화 걸기,전화 받기 할것입니다.
api만 이용하여 스카이프를 컨트롤하기위해서는 클라이언트가 로그인 되어 있어야 합니다.

C#에서 스카이프를 사용하기위해서는 재공된 Skype4COM.dll를 마샬링 해주어야 하는데......
이미 누군가가 해논게 있습니다. ㅋ

코드 플랙스 - Skype for VisualStudio

이곳에서는 비주얼 스트디오 sdk를 이용하여 스카이프 프로젝트를 생성할수 있게 되어 있지만 굳이 그렇게 까지 쓸필요는 없고 'SKYPE4COMLib'만 유징해서 사용하시면 됩니다.


 
0.UI 구성
저는 wpf 프로젝트로 하겠습니다만....C#프로젝트라면 별상관은 없습니다.(레이아웃 코드만 다를 뿐이니까요 ㅎㅎㅎ)


전역변수로 스카이프 클래스를 하나 선언해 두셔야 합니다.

/// 
/// 스카이프 클래스
/// 
private SkypeClass oSkype = null;


이 객체가 지금 떠있는 스카이프의 객체입니다.
스카이프api에 접근하기위해서는 이 객채를 통해야 합니다.


 
1.친구 목록 받아오기
일단 친구 목록이 있어야 메시지를 보내던 통화를 하던 하지 않겠습니까?ㅎㅎㅎ
친구 목록 받아오는 방법부터 알아보겠습니다.

//친구 목록
		void butGetFriend_Click(object sender, RoutedEventArgs e)
		{
			//친구 목록을 가저 옵니다.

			Friend oFriend = null;
			User user = null;

			//친구 목록을 받아 옵니다.
			UserCollection listTemp = this.oSkype.Friends;
			int nMax = listTemp.Count;

			//리스트 삭제
			lbFriend.Items.Clear();

			//인덱스가 1부터 시작이라 여러가지로 불편하네-_-;
			for( int i = 1; i <= nMax ; ++i )
			{
				user = listTemp[i];
				oFriend = new Friend();
				oFriend.labName.Content = user.FullName;
				lbFriend.Items.Add(oFriend);
			}

		}

		/// 
		/// 리스트에 선택된 유저의 인덱스를 받아 옵니다.
		/// 
		/// 
		private int GetSeletUserIndex()
		{
			//사용자 인덱스를 받아온다.
			int nSelectIndex = lbFriend.SelectedIndex;

			//인덱스가 1부터 시작하기 때문에 인덱스를 더해 준다.
			++nSelectIndex;

			return nSelectIndex;
		}


친구 목록이 가져와 진다!

참고로 Echo / Sound Test Service는 api로 접근하면 생성되는 유저입니다.
테스트용으로 사용할수 있습니다.


 
2.메시지 주고 받기
일종의 메신저 기능인 메시지주고 받기를 해보겠습니다.


 
2-1. 메시지 받기
당연한 이야기겠지만 메시지를 받기 위해서는 연결된 이벤트가 필요합니다.

생성자()
{
            //메시지가 오면 발생합니다.
            this.oSkype.MessageStatus += new _ISkypeEvents_MessageStatusEventHandler(oSkype_MessageStatus);
}

/// 
/// 메시지가 오면 발생합니다.
/// 
/// 
/// 
void oSkype_MessageStatus(ChatMessage pMessage, TChatMessageStatus Status)
{
      //다른사람이 보낸 메시지 인지?
      if (Status == TChatMessageStatus.cmsReceived)
      {
            //메시지를 발생시킨다.
            ChatMessage(pMessage.Sender, pMessage.Body);
            TextBox1.Text = TextBox1.Text + "\n" + pMessage.Sender.FullName + " : " + pMessage.Body;
      }
}

이렇게 하면 메시지를 받을수 있습니다.



 
2-2.메시지 보내기
친구목록을 받은후 선택한 친구에게 메시지를 보내봅시다.
//샌드 클릭
        void btnSend_Click(object sender, RoutedEventArgs e)
        {
			//메시지를 날리다.
			User oUser = this.oSkype.Friends[GetSeletUserIndex()];
			oSkype.SendMessage(oUser.Handle, txtSendText.Text);
        }


헛?
참 쉽죠?
ㅎㅎㅎ

사실 예외처리가 안들어가서 그렀습니다 ㅡ.-;;;;
예외처리를 알아서들 넣으세요 ㅎㅎㅎ


헛!
실수로 자기 메시지 처리하는 코드를 안넣었군요-_-;;;;
뭐 간단한 처리니까 알아서 할수 있겠네요 ㅎㅎㅎ


 
3.통화하기
스카이프의 꽃!!!!!
꽃보다 무료통화!!!!
네 바로 통화입니다.


 
3-1.전화 받기
전화도 메시지와 마찬가지로 이벤트가 넘어옵니다.
전화가 오는 이벤트는 _ISkypeEvents_Event_CallStatus입니다.

/// 
/// 받은 전화의 아이디.
/// 
private int m_nRingingID = 0;

생성자()
{
            //통화 상태 변경되면 발생합니다.
            this.oSkype._ISkypeEvents_Event_CallStatus += new _ISkypeEvents_CallStatusEventHandler(oSkype__ISkypeEvents_Event_CallStatus);
}

void oSkype__ISkypeEvents_Event_CallStatus(Call pCall, TCallStatus Status)
{
	//콜이 왔다!

	//객체 id 복사
	this.m_nRingingID = pCall.Id;

	switch(Status)
	{
		case TCallStatus.clsRinging:	//전화가 왔다.
			TextBox1.Text = TextBox1.Text + "\n" + e.CallDisplayName + " : " + "전화 왔음";
			break;
		case TCallStatus.clsFinished:	//전화 종료
			TextBox1.Text = TextBox1.Text + "\n" + e.CallDisplayName + " : " + "전화 종료";
			break;
	}
}

void btnResponse_Click(object sender, RoutedEventArgs e)
{
	//전화를 받는다.
	try
	{
		this.oSkype.get_Call(this.m_nRingingID).Answer();
	}
	catch
	{
	}
}

void btnFinish_Click(object sender, RoutedEventArgs e)
{
	//전화를 끊는다.
	try
	{
		this.oSkype.get_Call(this.m_nRingingID).Finish();
	}
	catch
	{
	}

}


일단 전화에 관련된 이벤트가 발생하면 _ISkypeEvents_Event_CallStatus가 호출됩니다.
어떤 이벤트인지는 TCallStatus Status로 넘어 오죠.

이때 TCallStatus.clsRinging는 상대방으로 부터 전화가 왔다는 것이고 TCallStatus.clsFinished가 오면 전화가 끊겼다(어떤식으로든 통화가 종료되면) 입니다.

여기서 주의할점은 내가 이 콜을 컨트롤 하기위해서는 콜의 id가 필요하다는 것입니다.
그렇기때문에 전역변수로 m_nRingingID를 선언하여 이 콜을 컨트롤 하기위해서 콜이 왔을때 해당 정보를 빽업해 둡니다.
그후 this.oSkype.get_Call(this.m_nRingingID)를 이용해 컨트롤하려는 콜을 불러와 사용합니다.

여기서도 예외처리가 빠진것이 있는데 현재 콜의 아이디가 _ISkypeEvents_Event_CallStatus에서 온 콜아이디와 같인지 확인을 안하고 있습니다.
이렇게 되면 콜을 여러개 받는경우 원하는대로 컨트롤이 안될수 있습니다.



콜이 왔다!



통화 잘되고 있음


전화가 끊겼네


 
3-2.전화 걸기
메시지 보내기와 마찬가지로 전화걸기고 친구 목록을 가저오고 난뒤 선택을 하고 걸기를 하셔야 합니다.



void btnCall_Click(object sender, RoutedEventArgs e)
{
   //전화를 건다.
 
  //사용자가 오프라인 상태인 경우 PlaceCall 명령은 실패합니다. 실패를 방지하려면 사용자 상태를 확인하고 필요한 경우 온라인으로 변경 :
   if (TUserStatus.cusOffline == this.oSkype.CurrentUserStatus)
   {
         this.oSkype.ChangeUserStatus(TUserStatus.cusOnline);
   }

   //열려있는 콜이 있으면 닫는다.
   CallFinish();

   //사용자 개채를 만든다            
   User oUser = null;

   try
   {
        oUser = this.oSkype.Friends[GetSeletUserIndex()];
   }
   catch
   {
         //유저를 찾지 못했습니다.
         return;
   }

   //전화 하는 장소:
   m_oCall = this.oSkype.PlaceCall(oUser.Handle, "", "", "");
}


PlaceCall를 이용하여 통화요청을 할수 있으며 이후 동작은 전화 받을 때와 같습니다.
PlaceCall의 매개변수는 모두 유저 핸들이며 여러명에게 한번에 걸때는 해당 유저 핸들러를 넣으시면 됩니다.

원래는 PlaceCall을 요청한뒤 받는 콜의 상태가 변해야 하는데....
버그인지 아니면 이것이 예전버전과 안맞는 것인지 도움말 파일에 들어있는 샘플코드대로 만들면 계속 같은 값만 들어오는 현상이 있습니다.

그래서 몇가지 태스트를 해보았으나....딱히 변하는 값을 전달하는 것을 찾지 못했습니다.
결국 다른콜이 올때나 요청할때 가지고 있는 콜(m_oCall)을 끝내주는 방법을 사용하셔야 합니다.
어차피 가지고 있는 콜이 끝나지 않은 상태에서도 다른동작에는 이상이 없기 때문에 이렇게 처리 하셔도 됩니다.
뭐....그 이후에 오는 내용(응답없음, 통화 실패 등등..)을 처리할 방법이 없습니다만......조만간 찾을수 있겠죠? ㅎㅎㅎ


우리에 테스트양에게 전화를 걸어 보았습니다 ㅡㅡㅋ




  1. passioni 2012.07.18 15:41  Address  Edit/Delete  Reply

    제일 처음 친구목록 받아오는 부분에서 Friend가 형식 또는 네임스페이스를
    찾을수 없다고 하는데요...
    어떻게하면 오류를 잡을수 있는 건가요?ㅠ_ㅠ

    • Favicon of https://blog.danggun.net BlogIcon 당근천국 2012.07.20 09:55 신고  Address  Edit/Delete

      SKYPE4COMLib를 유징해주시면 됩니다.
      아니면 Friend에다 커서를 두고 자동유징(컨트롤+.) 눌러 해당 SKYPE4COMLib가 정상적으로 프로젝트에 참조가 되었는지 확인 가능합니다.

  2. passioni 2012.07.20 12:56  Address  Edit/Delete  Reply

    SKYPE4COMLib를 유징했는데도 그런 오류가 자꾸떠서요...ㅜㅜ
    http://pds24.egloos.com/pds/201207/20/83/f0057483_5008d4cae8982.jpg/

    • Favicon of https://blog.danggun.net BlogIcon 당근천국 2012.07.23 11:13 신고  Address  Edit/Delete

      SKYPE4COMLib가 정상적으로 로드되었으면 Friend를 사용할수 있습니다.
      오래되서 기억은 안나는데 일단 자동유징(컨트롤+점(.))을해보시기 바랍니다.
      만약 자동완성메뉴가 뜨지 않는다면 dll참조를 지웠다가 다시 해보시기 바랍니다.

  3. 호류 2014.05.18 17:04  Address  Edit/Delete  Reply

    혹시 자신의 스카이프아이디를 받아올려면 어떻게해야되나요?

    • Favicon of https://blog.danggun.net BlogIcon 당근천국 2014.05.19 03:01 신고  Address  Edit/Delete

      오래되서 기억이 나지 않는데...
      'SkypeClass.ID' 나 'SkypeClass.MyID'를 해보시고 안되면 직접 찾으셔야 할것 같습니다.

댓글 작성

이름
패스워드
홈페이지
비밀글