Created
January 26, 2024 15:12
-
-
Save clichedmoog/8de4fa860b5ebbdd2a59c5fe7b4558b9 to your computer and use it in GitHub Desktop.
롱 폴링을 이용한 알림 확인 코드 예제
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 로그이 필요 데코레이터 | |
# REST API에 오류철 핸들러 데코레이터 | |
@decorators.ajax_error_response_v2 | |
@decorators.ajax_login_required_v2 | |
def notifications(request): | |
data = {} | |
user = request.user | |
# 파라메터에 따라 몇 가지 동작을 지원함 | |
if request.method == 'GET': | |
# count 파라메터는 곧바로 뱃지 갯수 가져오기 | |
if 'count' in request.GET: | |
count = Notification.badge_count(user) | |
data['count'] = count | |
# change는 50초 동안 실행하면서 5초에 한번씩 뱃지 숫자가 변경되었나 확인 | |
elif 'change' in request.GET: | |
count = Notification.badge_count(user) | |
data['count'] = count | |
for i in range(10): # run during 50 seconds + excution time | |
count = Notification.badge_count(user) | |
if data['count'] != count: | |
items = [] | |
data['count'] = count | |
objs = Notification.objects.filter(user_id=user.pk) \ | |
.filter(modified__gte=user.notified) | |
for obj in objs: | |
item = obj.v2_to_dict() | |
items.append(item) | |
data['items'] = items | |
break | |
time.sleep(5) | |
# 둘다 아닌경우는 알림 내용을 가져옴 | |
else: | |
items = [] | |
per_page = request.GET.get('n', 99) | |
page = request.GET.get('p') | |
objs = Notification.objects.filter(user=user) | |
# pagination if required | |
if page: | |
paginator = Paginator(objs, per_page) | |
try: | |
objs = paginator.page(page) | |
except EmptyPage: | |
objs = [] | |
for obj in objs: | |
item = obj.v2_to_dict() | |
items.append(item) | |
data['items'] = items | |
# PUT인 경우 뱃지 갯수 클리어 | |
elif request.method == 'PUT': | |
user = request.user | |
Notification.clear_badge(user) | |
data['count'] = 0 | |
return json_response(request, data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var do_poll = function(count) { | |
// AngularJS 1.x에서는 setInterval()에 해당하는 $interval()을 지원핮 않아서 $timeout()사용 | |
$timeout(function() { | |
// 60초까지 기다림 | |
$scope.polling_promise = ajax('GET', 'user/notifications?change', {}, undefined, 60000) | |
.success(function(response, status, headers, config) { | |
// 성공시 뱃시 카운트를 화면ㅇ 표시 | |
if (typeof response['data']['count'] !== 'undefined') { | |
$scope.notification_count = response['data']['count']; | |
if ($scope.notification_count > 99) { // Display as '99+' when reached maximum count | |
$scope.notification_count = '99+'; | |
} | |
} | |
if (typeof response['data']['items'] !== 'undefined') { | |
angular.forEach(response['data']['items'].reverse(), function(item) { | |
// replace notification if exist or add at first position | |
if (!search_replace_array($scope.notifications, item, 'id')) { | |
$scope.notifications.unshift(item); | |
} | |
}); | |
} | |
do_poll(); | |
}).error(function(response, status, headers, config) { | |
// 오류인 경우 다시 폴링하거나 로그인 하지 않았다면 폴링을 중단 | |
if (status == 403 && response['error'] && response['error']['code'] == 1300) { | |
$scope.stop_polling(); | |
} else { | |
do_poll(); | |
} | |
}); | |
// 다시 폴링을 시작하면 5초 기다리고 나서 시작함 | |
}, 5000); | |
}; | |
$scope.start_polling = function() { | |
ajax('GET', 'user/notifications?count', {count: true, poll: 0}) | |
.success(function(response, status, headers, config) { | |
if (response['data'] && response['data']['count']) { | |
$scope.notification_count = response['data']['count']; | |
} | |
}).error(function(response, status, headers, config) { | |
}).always(function() { | |
}); | |
$scope.polling_promise = do_poll(); | |
}; | |
$scope.stop_polling = function() { | |
if ($scope.polling_promise) { | |
$timeout.cancel($scope.polling_promise); | |
} | |
$scope.polling_promise = null; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment