트위터 전광판 페이지 개발

예전에 사용하다가 방치해 둔 블로그에 새 댓글이 달렸다는 알림 메일이 왔습니다.
이전에 facebook open api를 다룬 포스팅을 남긴 적이 있는데, 그 글의 댓글로 open api를 사용한 단기 알바를 해 보겠냐는 제의가 들어왔던 것이었습니다.
작업할 시간은 있었지만 굳이 일을 해야 할 필요성을 느끼지 못해서 처음에는 그냥 지나쳐 버렸습니다.
그렇지만 처음으로 open api를 사용한 웹개발을 해볼 수 있다는 설렘을 이기지 못하고, 결국 댓글을 남긴 분께 연락을 드렸습니다.

작업할 내용은 ASP 환경에서 twitter open api를 사용하여 특정 사용자(들)의 트윗을 가져와서 웹브라우저 상에 출력하는 일이었습니다.
제가 주력으로 사용하는 언어인 PHP를 사용할 수 없다는 점이 걸리기는 했지만, javascript api를 사용하면 해결될 것이라고 생각하고 작업을 시작했습니다.

계획은 제가 ASP 프로그래밍을 배운 적이 없기 때문에 순수 javascript로 작업하는 것이었습니다.
thread, jQuery를 사용하여 일정 간격으로 트위터 서버로부터 트윗을 가져오고
템플릿 파일을 읽어 특정 문자열을 트윗 데이터로 치환하도록 구현했습니다.

문제점 #1. cross site 보안 문제
client(웹페이지)에서는 보안 문제로 인해 몇 가지 예외를 제외하고는 다른 도메인에 접근할 수 없습니다.
대표적인 예외가 img 태그입니다.
이런 원칙에 따라 javascript 상에서도 트위터 api 서버로(즉, 다른 도메인으로) ajax 호출을 할 수 없습니다.
이를 해결하기 위해 JSONP를 사용하였습니다.
JSONP는 client에서 다른 도메인으로 ajax 호출을 할 수 있도록 합니다.
다만 그 다른 도메인의 페이지에서 반환하는 값이 json 형식이어야 합니다.

문제점 #2. ajax error 처리 문제
JSONP를 사용하여 다른 도메인으로 ajax 호출은 할 경우, 호출이 success한 경우의 콜백 메서드는 잘 작동하지만, 호출이 실패한(error) 경우에는 콜백 메서드가 실행되지 않는 문제점이 있습니다.
이를 해결하기 위해 timer를 사용하였습니다.
ajax를 호출할 때에 setTimeout()으로 에러처리 콜백 메서드를 호출할 timer를 만들어 둔 뒤, 호출이 success 한 경우에는 clearTimeout()을 통해 timer를 해제하도록 만들었습니다.

문제점 #3. rate limiting 문제
트위터 서버에는 api 호출에 rate limiting이 있습니다.
인증받지 않은 호출은 1시간에 150회, 인증받은 호출은 1시간에 350회까지 가능합니다.
특정 트위터 계정들의 트윗을 가져오기 위해 각각의 특정 트위터 계정에 대해 api 호출을 하면 금세 인증 횟수 제한에 걸립니다.
이를 해결하기 위해 별도의 트위터 계정을 생성하고 그 계정이 특정 계정들을 follow하도록 하고, 웹페이지에서는 생성한 트위터 계정의 timeline을 가져오도록 하려면 oauth 인증이 필요하므로 javascript만으로는 구현하기 어렵거나 복잡해집니다.
이를 해결하기 위한 방법으로 별도의 트위터 계정을 생성하고, 그 계정에 list를 추가한 뒤, 특정 트위터 계정들을 그 list에 추가하는 방법을 택했습니다.
list의 timeline을 가져올 때에는 인증이 불필요한데다 list에 대해 한 번 api를 호출하면 list에 속한 모든 트위터 계정들의 트윗을 가져오므로 rate limiting에도 걸리지 않게 됩니다.

문제점 #4. 이미지 출력 문제
트위터에서는 얼마 전부터 트윗에 이미지 첨부 기능을 제공합니다.
트윗을 가져오는 api를 호출하면 entities라는 태그 내에 이미지에 대한 url을 포함시키고 있는 것을 볼 수 있습니다.
그러나 아직 많은 사용자들은 yfrog나 twitpic을 사용하고 있기 때문에 이런 경우에도 웹페이지에서 곧바로 이미지를 출력해주기 위해서는 다른 도메인에 접속해서 parsing하는 부분이 필요합니다.
앞서 언급한 대로 javascript에서는 다른 도메인에 접속할 수 없기 때문에 javascript로만 해결하기는 어렵습니다.
이를 해결하기 위해 어쩔 수 없이 asp.net를 사용해서 코딩해야 했습니다.
yfrog.com이나 twitpic에 대한 링크를 별도로 만든 .aspx 파일에 전달하면 이 파일에서 그 링크에 접속하여 parsing을 한 뒤에 image 파일의 경로를 반환하도록 했습니다.

문제점 #5. 날짜 인식 문제
트위터에서 api 호출에 대해 반환한 json 객체 내의 날짜 표기 형식을 javascript의 Date 객체 생성에 곧바로 이용할 수 없었습니다.
이를 해결하기 위해 substring() 메서드를 사용하여 Date 객체 생성에 이용했습니다.

문제점 #6. json 객체 내의 null 문제
json 객체 내에 entities나 media 태그가 없는지 판단하는 과정에서 자꾸만 null 에러가 발생하면서 작동이 멈추었습니다.
매번 객체가 null이나 undefined 인지 판단하기도 어려웠을 뿐 아니라 코드가 길어지고 어려워졌습니다.
이를 해결하기 위해 try~catch 를 사용하여, entities나 media 태그가 없는 경우 catch 에서 처리하도록 했습니다.

문제점 #7. 다른 환경에서 실행되지 않는 문제
제 컴퓨터에서 개발할 때에는 .aspx 파일 실행이 잘 되었지만, 의뢰인의 서버에서는 잘 실행되지 않았습니다.
이를 해결하기 위해 publish 과정에서 생성된 Web.config, bin 폴더를 웹주소 루트에 위치시켰습니다.
또한 웹서버에서 asp.net의 버전을 동일하게 맞추어 준 뒤에는 문제 없이 실행되었습니다

문제점 #8. Chrome에서 실행되지 않는 문제
인터넷 익스플로러에서는 잘 실행되었지만 Chrome 브라우저에서는 제대로 작동하지 않았습니다.
개발자 도구로 에러나는 부분을 찾아보니 Date 객체를 생성하는 부분에 오류가 있었습니다.
new Date(“0000-00-00 00:00:00”)으로 Date 객체를 생성하였더니 IE에서는 문제가 없었지만 Chrome에서는 에러를 발생시켰습니다.
이를 해결하기 위해 new Date(“2001-01-01 00:00:00”)으로 Date 객체를 생성하였더니 Chrome에서는 잘 인식했지만 인터넷 익스플로러에서는 에러를 발생시켰습니다.
결국 new Date(2001, 1, 1)을 사용하니 두 브라우저에서 모두 이상 없이 작동했습니다.

문제점 #9. javascript 정규식 패턴 문제
트윗을 출력할 때에 템플릿에 맞추어 출력하는 과정에서 replace() 메서드를 사용하였습니다.
템플릿 파일 내에는 {screen_name}, {text} 등이 포함되어 있고, 이 부분을 찾아서 적절한 값으로 치환하는 방식을 사용했습니다.
data.replace(“{name}”, twit_item[“name”]) 과 같은 구문을 사용했는데, 가끔 제대로 작동하지 않는 등의 문제가 있었습니다.
이를 해결하기 위해 몇 시간이나 매달렸지만 제대로 되지 않았고, 결국 .aspx 파일을 ajax로 호출하여 GET으로 전달하는 방식을 사용하게 되었습니다.
나중에 알게 된 사실은, javascript에서 정규식 패턴은 “를 사용하여 감싸는 것이 아니라는 것이었습니다.
즉, 패턴에 “/      /im”라고 입력하면 슬래시 안쪽을 찾은 것이 아니라 쌍따옴표 안쪽을 찾는 것입니다.
원하는 결과를 얻기 위해서는 쌍따옴표 없이 /     /im을 사용했어야 합니다.

관련 포스트

답글 남기기

이메일 주소를 발행하지 않을 것입니다.