Hard Code Golf: создать чат


13

Cue Storyline: это начало 21-го века, и большинство вещей ушли в прошлое. Тем не менее, вы и ваши коллеги-разработчики кода стремитесь воссоздать 90-е годы. В рамках этой задачи вы должны воссоздать минималистичный чат.

Цель: создать чат с как можно меньшим количеством байтов. Программы, которые вы пишете, должны функционировать как простой сервер, который обслуживает веб-страницу, которая позволяет пользователям размещать текст на экране.

Фактическая цель: фактически разместить рабочий чат с вашего компьютера. Вам не нужно этого делать, но так намного веселее.

Требования:

  • Пользователи должны быть в состоянии дать себе имя пользователя, которое длится для сеанса
  • Пользователи должны иметь возможность многократно печатать и отправлять текст, который будет отображаться другим пользователям.
  • Каждый пользователь должен иметь возможность видеть текст, представленный всеми пользователями, вместе с именами отправителей, и информация должна отображаться в хронологическом порядке.
  • На странице также должно отображаться количество людей в сети и список их имен
  • Ваш чат должен быть доступен любому человеку в Интернете, который знает, где его найти (например, знает IP-адрес).
  • Он должен функционировать в современных веб-браузерах.

Все остальное зависит от вас!

Материалы:

  • Должен включать исходный код или ссылку на исходный код
  • Должны включать скриншоты функционального чата
  • Должен включать общий размер в байтах всех написанных вами программ / файлов, необходимых для его работы.

Эта задача была в песочнице некоторое время, так что, надеюсь, все изломы были решены.


1
было бы допустимо, если бы мы заставляли участников чата набирать каждый из их ответов в течение девяти секунд?
— Джон Дворжак

Я думаю, что 9 секунд, вероятно, слишком мало. Впрочем, что-то вроде 99 секунд может сработать. Я никогда не думал о том, чтобы ограничивать время для болтунов.
— PhiNotPi

определить "онлайн". Нужно ли публиковать сообщения перед выгрузкой, хватит ли 5с таймаута, или нам даже разрешено требовать, чтобы люди никогда не выходили из системы?
— Джон Дворжак

Разрешено ли нам разрешать HTML-инъекцию и другие вещи, которые могут нарушить работу чата (при условии, что мы не навредим нашему компьютеру)?
— Джон Дворжак

На самом деле, вы можете уточнить, "введите каждый из их ответов в течение девяти секунд?" Под «онлайн» я подразумеваю список людей, которые в настоящее время просматривают чат-комнату, например, если чат-комната открыта в окне браузера. Тайм-аут будет в порядке.
— PhiNotPi

Ответы:


18

PHP + JQuery + HTML + CSS, 1535 байт

Это представление больше склоняется к тому, что ФП считает «фактической целью». Это полнофункциональный чат-сервер, который может быть размещен практически на любом веб-сервере.

Функциональность включает в себя:

  • Уведомления, когда пользователи входят или выходят из чата.
  • Уведомления, когда пользователи меняют свой псевдоним.
  • Опрос в режиме реального времени для новых сообщений, без создания избыточного трафика сервера или нагрузки на сервер.
  • Макет и удобство использования очень напоминают существующие клиенты чата, такие как X-Chat.

Чтобы стать сеансом, введите псевдоним в соответствующем поле и нажмите Tabили Enterдля отправки. Если псевдоним уже используется, вы будете уведомлены. Отправка сообщений также осуществляется через Enter.

Для вашего удобства архив всех файлов можно найти здесь: chat.zip (выберите «Загрузить» в меню «Файл»). Для установки распакуйте в веб-каталог на любом сервере с PHP 5.4 или выше.

Предостережения:

  • IE 8 или ниже будет вращаться в бесконечный цикл при опросе, потому что по какой-то неизвестной человечеству причине все Ajax-запросы кэшируются по умолчанию. Это также не позволяет вам отправлять одно и то же сообщение дважды и правильно обновлять список пользователей. Это можно исправить, добавивcache:false к каждому запросу Ajax.
  • Во всех версиях IE сообщения не будут отправляться нажатием Enter, поскольку changeсобытие не вызывается (однако нажатие 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()>

ccc (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 байт). C пропускает изменения в «базе данных».

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

p.php (151 байт) P ОЛЛС для новых сообщений

<?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 байт) Возвращает список пользователей н Эймс

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

l.php (98 байт) Пользователь имеет л EFT (закрыли их браузер)

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

Я думаю, что вы можете обойтись onchange=uбез скобок. Однако вы не получите согласованного контекста, но он вам все равно не нужен.
— Джон Дворак

Можете ли вы сделать учебник немного более подробным? Я хочу установить это на Mac.
— Хайкам

@Peanut Я набрал несколько инструкций: codepad.org/UKGwb4g2 . Я работаю вслепую, но это, вероятно, сработает.
— Примо

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: значения по умолчанию - это просто ссылки на то, что вы передали. Если это изменчивый объект, он просто приходит на прогулку.

Другой, которым я редко пользуюсь - карри!

Запуск сервера:

Запустите скрипт чата из python (например, python chat.py), а затем укажите в браузере http://localhost:8080что-то вроде

Скриншот

Python, 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-серверу
— Джон Дворжак

1
@JanDvorak Вот почему я не сделал эту ссылку.
— Boothby

1
Для тех, у кого уже есть служба, работающая через порт 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

Узел / Метеор JavaScript + HTML + CSS + веб-сокет: 1,105 байт

Вот один из них, использующий node.js / meteor . Очевидно написано в js, в реальном времени и с использованием веб-сокетов. Использует встроенные в метеор пакеты по умолчанию.

Это может быть намного меньше. Кроме того, он постоянен благодаря включенному монго (не то, чтобы это было хорошо).

Рабочий скриншот:

введите описание изображения здесь

Для выполнения установите Метеор.

Linux:

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 байта. Обратите внимание, что браузеры не очень требовательны - я не пытаюсь закрывать теги, и вам определенно не нужна косая черта в конце тегов (если это не требуется узлу?). Кроме того, убейте больше пробелов! Я вижу пару в javascript, и слишком много в html.
— Boothby
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.