하드 코드 골프 : 대화방 만들기


13

Cue Storyline : 21 세기 초반에 대부분의 것들이 과거의 일이되었습니다. 그러나 여러분과 동료 코드 골프 선수들은 1990 년대를 재현하기 위해 노력하고 있습니다. 이 도전의 일환으로 최소한의 대화방을 다시 만들어야합니다.

목표 : 가능한 적은 바이트로 대화방을 만듭니다. 귀하가 작성하는 프로그램은 웹 페이지를 제공하는 간단한 서버로서 기능해야하며,이 서버는 사용자가 텍스트를 화면에 게시 할 수 있도록합니다.

실제 목표 : 실제로 자신의 컴퓨터에서 작업중인 대화방을 호스트합니다. 이 작업을 수행 할 필요는 없지만이 방법은 훨씬 더 재미 있습니다.

요구 사항 :

  • 사용자는 세션 동안 지속되는 사용자 이름을 제공 할 수 있어야합니다
  • 사용자는 텍스트를 반복적으로 입력하고 제출할 수 있어야하며 이는 다른 사용자에게 표시됩니다
  • 각 사용자는 제출자의 사용자 이름과 함께 모든 사용자가 제출 한 텍스트를 볼 수 있어야하며 정보는 시간 순서대로 표시되어야합니다.
  • 또한이 페이지에는 온라인상의 인원수와 사용자 명 목록이 표시되어야합니다
  • 인터넷에서 채팅방을 찾을 수있는 곳 (예 : IP 주소)을 아는 사람이라면 누구나 대화방에 액세스 할 수 있어야합니다.
  • 최신 웹 브라우저에서 작동해야합니다.

다른 모든 것은 당신에게 달려 있습니다!

제출물 :

  • 소스 코드 또는 소스 코드에 대한 링크를 포함해야합니다
  • 기능적인 대화방의 스크린 샷을 포함해야합니다
  • 작성한 모든 프로그램 / 파일의 총 크기 (바이트)를 포함시켜야 작동합니다.

이 도전은 당분간 샌드 박스에 있었으므로 모든 꼬임이 해결되기를 바랍니다.


1
채터가 9 초 이내에 각 응답을 입력하도록하면 허용됩니까?
John Dvorak

아마 9 초가 너무 짧을 것 같습니다. 그래도 99 초와 같은 것이 작동 할 수 있습니다. 나는 채터에 시간 제한을 두는 것을 생각하지 않았습니다.
PhiNotPi

"온라인"을 정의하십시오. 언로드하기 전에 다시 게시해야합니까, 5 초의 시간 초과가 충분하거나 사람들이 절대 로그 오프하지 않는다고 주장 할 수 있습니까?
John Dvorak

대화방을 깨뜨릴 수있는 HTML 주입과 다른 것들을 허용 할 수 있습니까 (컴퓨터를 다치게하지 않는 한)?
John Dvorak

실제로, "9 초 내에 각 응답을 입력하십시오"를 명확히 할 수 있습니까? "온라인"이란 대화방을 브라우저 창에서 열어 놓는 것과 같이 현재 대화방을보고있는 사람들의 목록을 의미합니다. 타임 아웃이 좋습니다.
PhiNotPi

답변:


18

PHP + JQuery + HTML + CSS, 1535 바이트

이것은 OP가 '실제 목표'로 간주되는 것에 더 집중된 제출입니다. 즉, 거의 모든 웹 서버에서 호스팅 할 수있는 모든 기능을 갖춘 채팅 서버입니다.

기능은 다음과 같습니다.

  • 사용자가 대화방에 입장하거나 떠날 때 알림.
  • 사용자가 별명을 변경할 때 알림
  • 과도한 서버 트래픽이나 서버로드를 생성하지 않고 새 메시지에 대한 실시간 폴링.
  • X-Chat과 같은 기존 채팅 클라이언트와 매우 유사한 레이아웃 및 유용성

세션 인하기 위해, 해당 상자에 별칭하고 Enter 키를 누르 Tab거나 Enter제출합니다. 별칭이 이미 사용중인 경우 알림이 표시됩니다. 메시지 전송은을 통해서도 수행됩니다 Enter.

편의를 위해 모든 파일의 아카이브는 chat.zip (파일 메뉴에서 다운로드 선택)에 있습니다. 설치하려면 PHP 5.4 이상을 실행하는 서버의 웹 디렉토리에 압축을 푸십시오.

주의 사항 :

  • IE 8 이하는 폴링 중에 무한 루프로 회전합니다. 어떤 이유로 인해 인간에게 알려지지 않은 이유로 모든 Ajax 요청이 기본적으로 캐시되기 때문입니다. 또한 동일한 메시지를 두 번 보내고 사용자 목록을 올바르게 업데이트하지 못하게합니다. cache:false모든 Ajax 요청 에 추가하면이 문제를 해결할 수 있습니다 .
  • 모든 버전의 IE에서 change이벤트가 트리거되지 않으므로 Enter 키를 눌러도 메시지가 전송 되지 않습니다 (그러나 Tab 키를 누르면 작동 함). onkeypress핸들러 를 추가 하고 키가 Enter인지 확인한 다음을 호출하여이 문제를 해결할 수 있습니다 $(v).blur().focus().

즉, IE는 지원되지 않습니다.


고객

요소의 위치는 좀 더 견고 할 수 있지만 최소 창 크기는 약 ~ 800x600입니다.

chat.htm (190 바이트)

<script src=jquery.min.js></script>
<script src=c.js></script>
<link rel=stylesheet href=c.css>
<select id=u multiple></select><pre id=o></pre>
<input id=n onchange=u()><input id=v onchange=s()>

c.css (136 바이트)

i{color:#999}
#u{float:right;height:100%;width:200px;margin-left:10px}
#o{border:1px solid #999;height:93%;overflow-y:scroll}
#v{width:54%}

c.js (435 바이트)

var l
(function p(){
  $.ajax({url:'p.php',data:{n:$('#n').val()},success:function(d){
    $('#o').html(d).scrollTop(1e4);$('#u').load('n.php');
  },complete:p,timeout:2e4})
})()
function s(){
  $.get('s.php',{n:$(n).val(),v:$(v).val()})
  $(v).val('')
}
function u(){
  $.get('u.php',{l:i=l,n:l=$(n).val()}).fail(function(){
    alert("This name is already in use!")
    $(n).val(l=i)
  })
}
$(window).on('unload',function(){$.ajax({url:'l.php',data:{l:l},async:false})})

섬기는 사람

서버가 너무 많은 작은 덩어리로 분해되어 죄송합니다. 대안은 적절한 메시지 프로토콜 (JSON 인코딩 / 디코딩을 통해)을 사용하거나 if ... elseif ...존재하는 포스트 변수에 따라 큰 메시지를 사용하는 것 입니다. 별도의 스크립트를 작성하는 것만으로 필요한 스크립트를 요청하는 것이 훨씬 짧고 아마도 두 가지보다 간단합니다.

o.php (119 바이트) O '데이터베이스'에 연결하는 펜

<?$m=array_slice(unserialize(file_get_contents(m)),-300);
$u=unserialize(file_get_contents(u));$t=time();extract($_GET);

c.php (57 bytes) C 는 '데이터베이스'에 대한 변경을 생략합니다.

<?foreach([u,m]as$c)file_put_contents($c,serialize($$c));

p.php (151 바이트) P의 새 메시지 olls

<?for($t=time();@filemtime(m)<$t;usleep(1e3))clearstatcache();include('o.php');
foreach($m as$v)if($n&&$v[0]>=$u[$n])echo@date("[H:i]",$v[0])."$v[1]\n";

s.php (62 바이트) S 는 서버에 메시지를 종료

<?include('o.php');$m[]=[$t,"<b>$n</b>: $v"];include('c.php');

u.php (222 바이트) U의 SER 등록 또는 별칭 변경

<?include('o.php');if(!trim($n)||$u[$n])exit(header('HTTP/1.1 418'));
$m[]=[$t,$u[$l]?
"<i><b>$l</b> is now known as <b>$n</b>.</i>":
"<i><b>$n</b> has entered the chat.</i>"];
$u[$n]=$u[$l]?:$t;unset($u[$l]);include('c.php');

n.php (65 bytes) 사용자 n ames 목록을 검색합니다

<?include('o.php');foreach($u as$k=>$v)echo"<option>$k</option>";

l.php (98 바이트) 사용자가 리터의 송금 (폐쇄 브라우저를)

<?include('o.php');$m[]=[$t,"<i><b>$l</b> has left the chat.</i>"];
unset($u[$l]);include('c.php');

onchange=u괄호없이 할 수 있다고 생각합니다 . 그러나 일관된 컨텍스트를 얻지는 않지만 어쨌든 필요하지는 않습니다.
John Dvorak

튜토리얼을 좀 더 자세하게 만들 수 있습니까? Mac에서 이것을 설정하고 싶습니다.
haykam

@Peanut 나는 몇 가지 지침을 입력 : codepad.org/UKGwb4g2 . 나는 장님 일하고 있지만 아마도 효과가있을 것입니다.
primo

13

파이썬, 230

이것은 매우 작지만 사양에 맞는 것 같습니다. 지난 99 초 동안 채팅 한 사용자는 "페이지보기"로 계산됩니다.

import cherrypy as S,time
@S.quickstart
@S.expose
def _(n='',p='',l=["<form%sn value='%s'%sp%s'' type=submit>"],u={},t="><input name="):u[n]=time.time();l+=p and[n+':'+p];return'<br>'.join([k*(u[n]-99<u[k])for k in u]+l)%(t,n,t,t)

이것은 파이썬에서 내가 가장 좋아하는 트릭 중 하나를 사용합니다. 기본값은 전달 한 모든 것에 대한 참조입니다. 변경 가능한 객체 인 경우 타고 나옵니다.

내가 자주 사용하지 않는 또 하나-카레!

서버 실행

(예를 들어, 파이썬에서 채팅 스크립트를 실행 python chat.py한 후) 및 귀하의 브라우저를 http://localhost:8080같은 것을 볼 수

스크린 샷

파이썬, 442

이것은 실제로 사용하기에 좋습니다. 이것이 골프이기 때문에 나는 이것이 덜 만족스러운 해결책이라고 생각합니다. 이제 iframe과 키 처리가있는 양식을 남용하고 새로운 내용을 폴링하기 위해 메타 새로 고침을 수행합니다.

import time,cherrypy as S
class C:
 c=S.expose(lambda s:"<form action=w target=t method=post><input name=n><input name=p onkeyup='if(event.keyCode==13){this.form.submit();this.value=\"\"}'><br><iframe name=t width=640>")
 @S.expose
 def w(s,n='',p='',l=[],u={}):u[n]=time.time();l+=p and[n+':'+p];return'<meta http-equiv=refresh content="1;url=w?n=%s">'%n+','.join(k for k in u if(u[n]-9<u[k])*k)+'<hr>'+'<br>'.join(l[::-1])
S.quickstart(C())

버전 2


2
브라우저를 가리키고 http://localhost:8080/c HTTP 서버에 액세스 할 수 있을지 의심됩니다.
John Dvorak

1
@JanDvorak 그렇기 때문에 링크를 만들지 않았습니다.
boothby

1
port 8080에서 이미 서비스를 실행중인 사용자는 다른 포트를 사용하기 위해 다음을 추가 할 수 있습니다.S.config.update({'server.socket_port':8090})
primo

사용자뿐만 아니라 다른 사람 이 새 메시지를 보낼 때 채팅 창을 업데이트하는 것이 얼마나 어려울 까요? (현재 양식에서 새 메시지가 있는지 확인하려면 창을 업데이트하기 전에 빈 메시지를 제출해야합니다.)
primo

1
@primo 맞아! 사람들이 무언가를 말했는지 확인하는 방법입니다. 문제는 90 년대를 재연했다. 당시에는 가장 간단한 코드에서 제안한 인터페이스를 사용자가 받아들이기를 기대했지만 여전히 멋졌습니다. HP는 우리에게 RPN을 주었고 우리 는 그것을 좋아했습니다 . 201 * -er처럼 생각하면 1280 자 정도의 부풀림을 얻을 수 있습니다.
boothby

5

유성 : 575 자

나는 이것으로 많은 재미를 가지고 있었다! 응용 프로그램은 http://cgchat.meteor.com/에 게시되어 있습니다 .

chat.html : 171 자

<body>{{>b}}</body><template name="b">{{#if l}}Online: {{#each u}}{{n}}, {{/each}}<hr>{{#each m}}{{n}}: {{t}}<p>{{/each}}<hr><input>{{else}}Name: <input>{{/if}}</template>

lib / chat.js : 45 자

c=Meteor.Collection;u=new c('u');m=new c('m')

client / client.js : 359 자

j=$.now;s=Session;t=Template.b;t.events({'change input':function(){v=$('input').val();s.get('u')?(m.insert({n:s.get('u'),t:v}),u.update(u.findOne({n:s.get('u')})._id,{$set:{l:j()}})):(s.set('u',v),u.insert({n:v,l:j()}))}});t.l=function(){return !!s.get('u')};t.u=function(){return u.find({l:{$gt:(j()-20000)}}).fetch()};t.m=function(){return m.find().fetch()}

링크가 죽었습니다.
programmer5000

5

노드 / 유성 자바 스크립트 + HTML + CSS + 웹 소켓 : 1,105 바이트

다음은 node.js / meteor를 사용하는 것 입니다. js, 실시간 및 웹 소켓을 사용하여 작성되었습니다. 유성의 기본 내장 패키지를 사용합니다.

훨씬 작을 수 있습니다. 또한 포함 된 몽고를 통해 지속적입니다 (좋은 것은 아닙니다).

작동하는 스크린 샷 :

여기에 이미지 설명을 입력하십시오

실행하려면 유성을 설치하십시오.

리눅스 :

curl https://install.meteor.com | /bin/sh`

Windows : win.meteor.com

내 레포를 복제하고 유성을 실행하십시오.

git clone http://github.com/bradgearon/meteor-chat
cd meteor-chat
meteor

브라우저가 localhost : 3000을 가리 키도록하십시오

chat.js : 703 바이트 (클라이언트 / 서버) :

l='subscribe',d=[],n='n',i='i',b='b',c='click #',r='return ',u='u',y=0
f=Function,m=Meteor,o=m.Collection,p=new o(b),t=new o(u)
w=f('t.remove({i:d.pop()})'),g=f('_(d.length).times(w)')
m.isClient&&(h=Template.h,e=h.events={},m[l](b),m[l](u),s=Session,
w=f(r+'s.get(i)'),h.p=f(r+'p.find()'),h.t=f(r+'t.find()'),a=f('a','a','y=$("#3").val(),s.set(i,1)'),
e[c+'2']=f('p.insert({c:(y||"?")+": "+$("#l").val()})'),
e[c + '4'] = f('w()||m.call("x",$("#3").val(),t._connection._lastSessionId,a)')
)||(
m.startup(f('t.remove({}),p.remove({}),m.setInterval(g,100)')),j=f('h=this.id;h&&d.push(h)'),
m.methods({x:f('k','d','s=m.default_server.sessions[d].socket,s.on("close",j),t.insert({n:k,i:s.id})')}))

chat.css : 132 바이트

g{display:block;overflow-y:scroll;margin:10px;}
n{float:right;width:40%;min-height:100%;}
d{float:left;width:60%;min-height:100%;}

chat.html : 270 바이트

<body>
    {{> h}}
</body>
<template name="h">
<d>
<g>{{#each p}}{{c}}<br />{{/each}}</g>
<input id=l>{{this.k}}</input>
<input type=submit id=2 />
</d>
<n>
<g>{{#each t}}{{n}}<br />{{/each}}</g>
<input id=3 />
<input type=submit id=4 />
</n>
</template>

1
codegolf에 오신 것을 환영합니다! 이 파일 chat.html에는 254 바이트 만있는 것 같습니다. 브라우저는 엄청나게 까다 롭지 않습니다. 태그를 닫을 필요가 없으며 태그 끝에 슬래시가 필요하지 않습니다 (노드가 요구하지 않는 한). 또한 더 많은 공백을 제거하십시오! 자바 스크립트에는 몇 가지가 있으며 HTML에는 너무 많이 있습니다.
boothby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.