Ошибка 4. Не фиксировать договоренности
Вы общались с заказчиком и договорились, например, что макет сайта будет готов через три недели. Что начать нужно с каталога товара и корзины, а фото продукции взять не со старого сайта, а сходить по специальной ссылке, которую прислал клиент. Вы поговорили, но не записали важную информацию. Потом навалилось много текущих дел, и вы не учли никаких договоренностей, когда ставили задачи команде.
Работа над проектом началась, команда сделала макет. Но когда заказчик его посмотрел, оказалось, что все не так. Вы пытаетесь объяснить ситуацию, но никто не хочет слушать оправдания. Команда потратила силы и время зря, а теперь переделывает все после работы, но клиент недоволен. Не очень приятная ситуация, правда?
Важно!
Записывайте все договоренности и дублируйте заказчику по электронной почте. Это хороший способ ничего не потерять и не запутаться.. Источник
Источник
Определите причину ухода клиентов
Выяснить причину можно несколькими способами:
- спросить прямо — по электронной почте, телефону или через чат на сайте. Спросите, что именно не нравится клиенту и почему он перестал заказывать услуги или покупать товары. Чтобы пользователь был с вами честен и назвал реальную причину ухода, представьтесь не менеджером, а, к примеру, экспертом по качеству сервиса или директором по обслуживанию;
- опросить менеджеров — узнайте, почему их клиенты уходят. Естественно, не напрямую — так вам никто истинную причину не скажет. Опрос должен быть анонимным. Создайте опрос в Google-форме;
- поговорить с сотрудниками и постоянными клиентами — можно коллективно составить список из главных причин, по которым покупатели могут уходить, и решить, с какими из них вы в состоянии бороться.
Часто клиенты уходят к конкурентам, которые предлагают лучшие условия, или когда им не нравится ваш сервис. Случается и так, что человек просто меняет место жительства или перестает нуждаться в конкретной группе товаров — тогда он тоже уходит. Если с личными обстоятельствами бороться нельзя, то улучшать качество сервиса и становиться лучше конкурентов еще как можно.
Андрей Смирнов,
скриптолог, специализируется на продажах и переговорах:
— Есть 3 категории клиентов. Первая — те, которые сделали покупку один раз и пропали. Вторая — те, которые длительное время покупали, а потом перестали и ушли, скорее всего, переключившись на ваших конкурентов. А еще есть «спящие» клиенты — те, которые находятся в раздумьях. Вот их, в отличие от первых двух категорий, можно «разбудить»: рассылкой, звонками или SMS.
Читать по темеКлиенты уходят к конкурентам: почему и как их вернуть
Клиентское программирование
В случае программирования на стороне клиента клиент сначала будет ждать запуска сервера. Как только сервер будет запущен, он отправит запросы на сервер. После этого клиент будет ждать ответа от сервера. Итак, в этом вся логика взаимодействия клиента и сервера.
Чтобы инициировать запрос клиентов, вам необходимо выполнить следующие шаги:
1. Установите соединение
Самый первый шаг – установить соединение через сокет. Соединение через сокет подразумевает, что две машины имеют информацию о сетевом расположении друг друга (IP-адрес) и TCP-порте.
Вы можете создать Socket с помощью следующего оператора:
Socket socket = new Socket («127.0.0.1», 5000)
- Здесь первый аргумент представляет собой IP-адрес сервера.
- Второй аргумент представляет TCP-порт (число, обозначающее, какое приложение должно работать на сервере).
2. Связь
Для связи через соединение сокета потоки используются как для ввода, так и для вывода данных. После установления соединения и отправки запросов вам необходимо закрыть соединение.
Пример реализации сокетного соединения на стороне клиента
// A Java program for a ClientSide import java.net.*; import java.io.*; public class ClientProgram { // initialize socket and input output streams private Socket socket = null; private DataInputStream input = null; private DataOutputStream out = null; // constructor to put ip address and port public Client(String address, int port) { // establish a connection try { socket = new Socket(address, port); System.out.println("Connected"); // takes input from terminal input = new DataInputStream(System.in); // sends output to the socket out = new DataOutputStream(socket.getOutputStream()); } catch(UnknownHostException u) { System.out.println(u); } catch(IOException i) { System.out.println(i); }// string to read message from input String line = ""; // keep reading until "Over" is input while (!line.equals("Over")) { try { line = input.readLine(); out.writeUTF(line); } catch(IOException i) { System.out.println(i); } } // close the connection try { input.close(); out.close(); socket.close(); } catch(IOException i) { System.out.println(i); } } public static void main(String args[]) { Client client = new Client("127.0.0.1", 5000); } }
Простой Пример
Давайте испачкаем руки в самых основных примерах, связанных с клиентом и сервером . Это будет двустороннее коммуникационное приложение, в котором клиент приветствует сервер, а сервер отвечает.
Давайте создадим серверное приложение в классе с именем GreetServer.java со следующим кодом.
Мы включаем метод main и глобальные переменные, чтобы привлечь внимание к тому, как мы будем запускать все серверы в этой статье. В остальных примерах в статьях мы опустим этот тип более повторяющегося кода:
public class GreetServer { private ServerSocket serverSocket; private Socket clientSocket; private PrintWriter out; private BufferedReader in; public void start(int port) { serverSocket = new ServerSocket(port); clientSocket = serverSocket.accept(); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String greeting = in.readLine(); if ("hello server".equals(greeting)) { out.println("hello client"); } else { out.println("unrecognised greeting"); } } public void stop() { in.close(); out.close(); clientSocket.close(); serverSocket.close(); } public static void main(String[] args) { GreetServer server=new GreetServer(); server.start(6666); } }
Давайте также создадим клиент под названием GreetClient.java с этим кодом:
public class GreetClient { private Socket clientSocket; private PrintWriter out; private BufferedReader in; public void startConnection(String ip, int port) { clientSocket = new Socket(ip, port); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); } public String sendMessage(String msg) { out.println(msg); String resp = in.readLine(); return resp; } public void stopConnection() { in.close(); out.close(); clientSocket.close(); } }
Давайте запустим сервер; в вашей IDE вы делаете это, просто запустив его как Java-приложение.
А теперь давайте отправим приветствие на сервер с помощью модульного теста, который подтверждает, что сервер действительно отправляет приветствие в ответ:
@Test public void givenGreetingClient_whenServerRespondsWhenStarted_thenCorrect() { GreetClient client = new GreetClient(); client.startConnection("127.0.0.1", 6666); String response = client.sendMessage("hello server"); assertEquals("hello client", response); }
Не волнуйтесь, если вы не совсем понимаете, что здесь происходит, так как этот пример призван дать нам представление о том, чего ожидать в дальнейшем в статье.
В следующих разделах мы проанализируем связь сокетов , используя этот простой пример, и углубимся в детали с большим количеством примеров.
Пример 1 — клиент долго советуется с родственниками
2. Допустим, клиент говорит, что ему нужно посоветоваться: «Вы знаете, Алексей Иванович, на моей практике, когда люди берут паузу „на посоветоваться“ — их что-то удерживает. Поделитесь, я с удовольствием отвечу на ваши вопросы». Это вторая деликатная попытка прояснить, что его все-таки держит. Согласитесь, человек не уходил бы советоваться, если бы ему все нравилось. Хотя есть такие люди, которым все нравится, но у них такая позиция по жизни — надо «переспать» с мыслью. Здесь вы ничего не поделаете, нужно отпускать клиента, но ненадолго.
Фото: РИА новости
3. Поставьте себя на место соискателя. Вам нужна работа за рубежом — и если вам нужно посоветоваться, и вопрос для вас острый, ну разве вы не найдете время в этот же день или на следующий, чтобы пообщаться с родственниками или другими советчиками?
Две недели для получения совета — это перебор. Клиент забудет, как вас звать, или «остынет», эмоциональный запал пройдет. Поэтому, даже если вы клиента отпускаете посоветоваться, то с конкретной договоренностью. «Давайте так поступим, Алексей Иванович… Посоветоваться — это святое, я бы сам на вашем месте так же сделал. Если я примерно через дня 2 наберу, вы наверняка уже успеете с родственниками переговорить, нормально? В четверг, допустим, я зафиксирую созвон?» В мягкой форме, но вы все-таки берете инициативу и фиксируете следующий шаг.
4. Но случается, что, например, родственники советуют клиенту такое, что просто кошмар. И клиент говорит: «Вы знаете, мы пока решили взять паузу». Тогда вы ему в ответ: «Видимо, кто-то вас отговорил или что-то серьезное вас смутило… Поделитесь, я попробую ответить на вопросы. Это просто очень распространенная ситуация — родственники не до конца владеют информацией, но искренне переживают за вас, поэтому частенько отговаривают. В чем у вас загвоздка?»
Фото с сайта eyeem.com
5. Возможно, клиент поделится, что у него было в разговоре с родственниками. И в этом случае я сказал бы так: «Вы знаете, обычно в такой ситуации, как у вас, мы поступаем следующим образом: вы приходите к нам в офис вместе с тем, с кем советуетесь, вы вместе задаете все интересующие вопросы, мы еще раз проговорим варианты, и вам так будет легче принять взвешенное решение. Как насчет завтра, удобно будет?»
Специальные требования к серверу
В нашем случае лучше всего использовать сервер на основе цикла событий. Например, NodeJS, Kestrel или Twisted. Идея состоит в том, что при использовании потокового решения будет один поток на соединение. То есть, 1000 соединений = 1000 потоков. В решении на основе цикла событий у нас будет один поток для 1000 соединений.
- Вы можете принимать запросы EventSource только в том случае, если HTTP-запрос говорит, что он может принимать MIME-тип event-stream;
- Необходимо вести список всех подключенных пользователей, чтобы запускать новые события;
- Вы должны прослушивать сброшенные соединения и удалять их из списка подключенных пользователей;
- Вы должны поддерживать историю сообщений, чтобы при повторном подключении клиентов можно было отправить им пропущенные сообщения.
Мы получили все, чтобы приложение работало эффективно. Но столкнулись с некоторыми проблемами:
- Устаревшие прокси-серверы в некоторых случаях удаляют HTTP-соединения после короткого таймаута. Чтобы защитить соединения, авторы могут включать строку комментариев (начинающуюся с символа «:») каждые 15 секунд или около того.
- Авторы, желающие связать соединения источника событий друг с другом или с определенными ранее документами, могут обнаружить, что использование IP-адресов не работает. Отдельные клиенты могут иметь несколько IP-адресов (из-за наличия нескольких прокси-серверов) и отдельные IP-адреса могут иметь несколько клиентов (из-за совместного использования прокси-сервера). Лучше включать в документ уникальный идентификатор и передавать его как часть URL-адреса при установлении соединения.
- Использование chunked transfer encoding может уменьшить надежность HTTP протокола, если блокирование выполняется другим слоем, не подозревающим о требованиях к синхронизации. Если эта проблема возникнет, блокирование может быть отключено для обслуживания потоков событий.
- Клиенты, которые поддерживают ограничение на подключение к серверу через протокол HTTP, могут столкнуться с трудностями при открытии нескольких страниц сайта, если на каждой из этих страниц есть источник событий, расположенный в том же домене. Можно избежать этого, применяя механизм уникальных доменных имен для каждого соединения и разрешая пользователям включать функции EventSource для каждой страницы.
- Поддержка браузера и полифиллы: Microsoft Edge не поддерживает эту реализацию. Но существует полифиллы, которые позволяют решить данную проблему. Тем не менее, самый важный сегмент для SSE — это мобильные устройства, где браузеры IE / Edge распространены незначительно.
Некоторые из доступных полифиллов:
· Yaffle.
· amvtek.
· remy.
Бесплатное подключение и другие функции
Пользовательские агенты, работающие в контролируемых средах, могут отключить управление соединением с прокси-сервером в сети. В такой ситуации считается, что пользовательский агент включает как программное обеспечение мобильного устройства, так и сетевой прокси-сервер.
Например, браузер на мобильном устройстве, установив соединение, может обнаружить, что он находится в поддерживаемой сети, и попросить прокси-сервер сети взять на себя управление созданным соединением. Последовательность действий в такой ситуации может быть следующей:
- Браузер подключается к удаленному HTTP-серверу и запрашивает ресурс, указанный автором в конструкторе EventSource.
- Сервер отправляет случайные сообщения.
- В промежутке между двумя сообщениями браузер обнаруживает, что он неактивен, за исключением активности сети, связанной с поддержанием TCP- соединения, и решает переключиться в спящий режим для экономии энергии.
- Браузер отключается от сервера.
- Браузер связывается с сервисом в сети и просит, чтобы служба «push proxy» поддерживала соединение.
- Служба «push proxy» связывается с удаленным HTTP-сервером и запрашивает ресурс, указанный в конструкторе EventSource (возможно, включая HTTP-заголовок последнего события и т. д.).
- Браузер позволяет мобильному устройству перейти в спящий режим.
- Сервер отправляет другое сообщение.
- Служба «push proxy» использует технологию OMA push для передачи события на мобильное устройство, которое выходит из спящего режима на время, достаточное для обработки события. Затем возвращается в спящий режим.
Подобный подход может снизить объем передаваемых данных и привести к значительной экономии энергии.
Помимо реализации существующего API и формата передаваемых данных ext/event-stream также могут поддерживаться форматы фреймворка событий, определенные другими спецификациями.
Обзор
Термин сокет программирование относится к написанию программ, которые выполняются на нескольких компьютерах, в которых все устройства подключены друг к другу с помощью сети.
Существует два протокола связи, которые можно использовать для программирования сокетов: Протокол пользовательских дейтаграмм (UDP) и протокол управления передачей (TCP) .
Основное различие между ними заключается в том, что UDP не имеет соединения, что означает отсутствие сеанса между клиентом и сервером, в то время как TCP ориентирован на соединение, что означает, что сначала должно быть установлено исключительное соединение между клиентом и сервером для осуществления связи.
Этот учебник представляет введение в программирование сокетов по сетям TCP/IP и демонстрирует, как писать клиентские/серверные приложения на Java. UDP не является основным протоколом и как таковой может встречаться нечасто.
Сервер С Несколькими Клиентами
Несмотря на то, что предыдущий пример был улучшением по сравнению с первым, он все еще не является отличным решением. Сервер должен иметь возможность обслуживать множество клиентов и множество запросов одновременно.
Работа с несколькими клиентами-это то, что мы рассмотрим в этом разделе.
Еще одна особенность, которую мы увидим здесь, заключается в том, что один и тот же клиент может отключиться и снова подключиться, не получая исключения отказа в подключении или сброса соединения на сервере. Раньше мы не могли этого сделать.
Это означает, что наш сервер будет более надежным и устойчивым к многочисленным запросам от нескольких клиентов.
Мы сделаем это, чтобы создать новый сокет для каждого нового клиента и обслуживать запросы этого клиента в другом потоке. Количество клиентов, обслуживаемых одновременно, будет равно количеству запущенных потоков.
Основной поток будет выполнять цикл while, когда он прослушивает новые соединения.
Хватит разговоров, давайте создадим еще один сервер под названием EchoMultiServer.java. Внутри него мы создадим класс потока обработчика для управления коммуникациями каждого клиента в его сокете:
public class EchoMultiServer { private ServerSocket serverSocket; public void start(int port) { serverSocket = new ServerSocket(port); while (true) new EchoClientHandler(serverSocket.accept()).start(); } public void stop() { serverSocket.close(); } private static class EchoClientHandler extends Thread { private Socket clientSocket; private PrintWriter out; private BufferedReader in; public EchoClientHandler(Socket socket) { this.clientSocket = socket; } public void run() { out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { if (".".equals(inputLine)) { out.println("bye"); break; } out.println(inputLine); } in.close(); out.close(); clientSocket.close(); } }
Обратите внимание, что теперь мы вызываем accept внутри цикла while. Каждый раз, когда выполняется цикл while , он блокирует вызов accept до тех пор, пока не подключится новый клиент , а затем для этого клиента создается поток обработчика EchoClientHandler
То, что происходит внутри потока, – это то, что мы ранее делали на сервере Echo , где мы обрабатывали только одного клиента. Таким образом, Echo Multi Server делегирует эту работу EchoClientHandler , чтобы он мог продолжать прослушивать больше клиентов в цикле while .
Мы по-прежнему будем использовать Echo Client для тестирования сервера, на этот раз мы создадим несколько клиентов, каждый из которых будет отправлять и получать несколько сообщений с сервера.
Давайте запустим наш сервер, используя его основной метод на порту 5555 .
Для ясности мы все равно поместим тесты в новый набор:
@Test public void givenClient1_whenServerResponds_thenCorrect() { EchoClient client1 = new EchoClient(); client1.startConnection("127.0.0.1", 5555); String msg1 = client1.sendMessage("hello"); String msg2 = client1.sendMessage("world"); String terminate = client1.sendMessage("."); assertEquals(msg1, "hello"); assertEquals(msg2, "world"); assertEquals(terminate, "bye"); } @Test public void givenClient2_whenServerResponds_thenCorrect() { EchoClient client2 = new EchoClient(); client2.startConnection("127.0.0.1", 5555); String msg1 = client2.sendMessage("hello"); String msg2 = client2.sendMessage("world"); String terminate = client2.sendMessage("."); assertEquals(msg1, "hello"); assertEquals(msg2, "world"); assertEquals(terminate, "bye"); }
Мы могли бы создать столько тестовых случаев, сколько нам заблагорассудится, каждый из которых порождает нового клиента, и сервер будет обслуживать их все.
Сделайте реактивационную email-рассылку
- Определите, какие пользователи считаются неактивными или ушедшими — это могут быть клиенты, которые не совершали покупки больше трех месяцев или забыли оплатить ежемесячную подписку;
- Продумайте цепочку писем — в письмах должно быть что-то, что привлечет и замотивирует вернуться: скидка, подарок, бонус;
- Продолжайте работу с клиентами, которые отозвались на ваше предложение, а тех, кто проигнорировал письмо, удалите из базы и не настаивайте.
Реактивационное письмо от HeadHunter.
Евгения Сарычева,
руководитель направления «Инструменты продаж» журнала «Коммерческий директор», заместитель главного редактора журнала «Коммерческий директор»:
— Со скидками нужно быть осторожнее. Часто клиенты при последующих покупках так же хотят скидку. Например, это может произойти, если клиент недоволен качеством товара и хочет прекратить сотрудничество. В этом случае ему можно предложить 10-20% скидку при следующем заказе. Но представьте, если покупатель закажет продукцию на сумму 20 тыс. рублей, и тогда вам придется потерять 40 тыс. рублей прибыли. Поэтому предлагать скидки нужно аккуратно. Например, можно оговорить заранее лимит суммы, которую вы можете вернуть. Или предлагайте не скидку, на дополнительный сервис при повторном заказе.
Читать по теме
Окей, мы удалили неактивных клиентов из базы, что дальше? В статье рассказываем, как увеличить клиентскую базу и найти постоянных клиентов взамен ушедших.
Как CRM-система помогает не терять клиентов
Работа с потерянными клиентами без четкой структуризации неэффективна. Можно разделить аудиторию на неверные сегменты, кого-то забыть, что-то перепутать и в итоге так и не дождаться результата. С CRM-системой все упрощается:
- проще сегментировать клиентскую базу — система автоматически распределяет клиентов в нужные группы;
- известно все и про каждого клиента — для этого у них есть свои индивидуальные карточки, куда заносятся все детали сотрудничества;
- есть напоминания для менеджеров: когда нужно позвонить, кто давно не покупал, а кто покупает часто и заслуживает попасть в бонусную программу;
- можно легко настроить реактивационную цепочку писем прямо из системы;
- сложно запутаться и упустить регресс — CRM показывает откаты и подъемы в виде аналитических графиков.
В CRM вся база клиентов и данные об их активности — в одном месте.
Попробуйте несколько способов удержания и возврата клиентов и задействуйте для этого CRM-систему. Программа поможет сделать процесс работы с клиентами автоматизированным и уменьшит число потерянных покупателей, которые уходят просто потому, что менеджер о них забыл. Испытайте возможности CRM S2 в течение 7 бесплатных дней и сделайте выводы.
Пример 2 — клиент постоянно откладывает разговор
1. Моя любимая фраза в таких случаях: «Давайте начистоту, Алексей Иванович. Мы с вами начали общение месяц назад, с тех пор созваниваемся. Если есть какие-то сомнения серьезные, вопросы, которые мы не проговорили, — я с удовольствием на них отвечу, чтобы поставить какую-то точку, работаем мы или нет. Уверен, вы тоже хотите уже к какому-то решению прийти, что скажете? Если да — жду ваши реквизиты, если что-то смущает — скажите сейчас, обсудим». Таким образом я сохраняю позитив и не «наезжаю».
Фото с сайта gamespax.ru
2. Второй способ: «У нас с вами юбилей: мы уже почти месяц потихонечку принимаем решение, но, видимо, остались какие-то нюансы, которые мы не проговорили. Расскажите, в чем дело — я отвечу на вопросы».
3. Как вариант, можно сказать: «Знаете, как правило, в такой ситуации мы с клиентом встречаемся лично. По телефону разговор всегда быстрый, 3−5 минут, а встреча — это худо-бедно на минут 20. Попьем кофе, обсудим все детали, я уверен — примем взвешенное решение. Скажите, на вашей территории или на нашей встречаемся?» Так клиент думает не о том, встречаться или не встречаться, а сразу о месте встречи.
Ошибка 3. Сразу озвучивать стоимость проекта
Понятно, что клиент хочет в самом начале узнать, во сколько ему обойдется та или иная услуга. Вам кажется, что если не озвучить цену сразу, то он уйдет.
Источник
Тут нужно объяснить, что сможете рассчитать примерную стоимость только если будете понимать, чего конкретно хочет заказчик.
В разработке программного обеспечения трудно в самом начале предсказать стоимость проекта. Она зависит от количества функций и сложности ПО. Пока у вас слишком мало информации, чтобы понять, сколько будет стоить конечный продукт.
Важно!
Рассказать клиенту, что для разработки ПО этап аналитики обязателен. Только так вы сможете создать продукт, который ему нужен.. Если озвучить примерную стоимость, пока вы еще ничего не поняли про проект, то она может начать стремительно расти после выяснения потребностей
Чем больше функций у будущего сайта, тем выше его стоимость.
Если озвучить примерную стоимость, пока вы еще ничего не поняли про проект, то она может начать стремительно расти после выяснения потребностей. Чем больше функций у будущего сайта, тем выше его стоимость.
Ошибка 1. Не задавать вопросы
Это ошибка несет с собой много проблем. В процессе разговора вы внимательно слушали и кивали, но не задавали вопросов
Клиент рассказал все, кроме того, что важно. В итоге заказ есть, но нет никакой полезной информации
А если вы не знаете потребности клиента и его проблему, то как собираетесь ее решать?
Важно!
Выяснить, что за бизнес у заказчика и какие проблемы он хочет решить с помощью вашего продукта. Для этого задавайте открытые вопросы, на которые можно подробно ответить.. Источник
Источник
Примеры вопросов:
- Чем занимается ваша компания?
- Какую цель вы хотите достичь, сделав сайт/приложение?
- Какая у вас целевая аудитория?
- Кого вы считаете своими основными конкурентами?
Ошибка 6. Не учитывать контекст клиента
Вы позвонили клиенту, чтобы задать уточняющие вопросы. И сразу перешли к делу. Все детали обсудили и попрощались. Но при следующем разговоре выяснили: он вообще не помнит, что вы о чем-то договорились неделей раньше. Так получилось, что клиент в этот момент был на отдыхе, но не сказал вам об этом. Пока вы говорили, он не слушал внимательно: думал о своем.
Источник
Важно!
Всегда думайте о контексте клиента. Спросите, удобно ли ему сейчас разговаривать и уточните, сколько это займет времени.. Возможно, вы находитесь в разных городах или даже странах
Тогда нужно учитывать и разницу во времени. Уточните местоположение клиента раньше, чем предложите ему встретиться для обсуждения деталей.
Возможно, вы находитесь в разных городах или даже странах. Тогда нужно учитывать и разницу во времени. Уточните местоположение клиента раньше, чем предложите ему встретиться для обсуждения деталей.
Примеры вопросов:
- Вам удобно сейчас разговаривать? Это займет всего десять минут.
- Вам удобно будет встретиться завтра в 14:00, чтобы обсудить детали по проекту?
Ошибка 2. Пропускать презентацию компании
Вы так увлеклись, слушая клиента, что забыли рассказать о преимуществах компании. Кажется, вы были предельно внимательны и ничего не упустили. А собеседник не понял, чем ваша компания отличается от других, как ему кажется, точно таких же. Если у конкурентов нужные клиенту услуги стоят дешевле, то он уйдет туда, где можно заплатить меньше.
Источник
Важно!
Клиент ничего о вас не знает, помогите ему. Расскажите кратко об особенностях компании
Почему нужно заказать сайт именно у вас?
Как не надо |
Как надо |
---|---|
У нас большой опыт |
Мы делали сайты для таких крупных компаний, как… Вот примеры наших работ |
Сделаем быстро |
Работаем по скрам |
Сможете выбрать дизайн |
Сможете участвовать в процессе |
Программирование на стороне сервера
По сути, сервер создает экземпляр своего объекта и ждет запроса клиента. Как только клиент отправит запрос, сервер ответит на него.
Для кодирования серверного приложения вам понадобятся два сокета, и они следующие:
- ServerSocket, который ожидает клиентских запросов (когда клиент создает новый Socket()).
- Обычный старый сокет для связи с клиентом.
После этого вам нужно связаться с клиентом с ответом.
Пример реализации сокетного соединения на стороне сервера
// A Java program for a Serverside import java.net.*; import java.io.*; public class ServerSide { //initialize socket and input stream private Socket socket = null; private ServerSocket server = null; private DataInputStream in = null; // constructor with port public Server(int port) { // starts server and waits for a connection try{ server = new ServerSocket(port); System.out.println("Server started"); System.out.println("Waiting for a client ..."); socket = server.accept(); System.out.println("Client accepted"); // takes input from the client socket in = new DataInputStream( new BufferedInputStream(socket.getInputStream())); String line = ""; // reads message from client until "Over" is sent while (!line.equals("Over")) { try { line = in.readUTF(); System.out.println(line); } catch(IOException i) { System.out.println(i); } } System.out.println("Closing connection"); // close connection socket.close(); in.close(); } catch(IOException i){ System.out.println(i); } } public static void main(String args[]){ Server server = new Server(5000); } }
После настройки как клиентской, так и серверной стороны вы можете сначала запустить программу на стороне сервера. После этого вам необходимо запустить клиентскую программу и отправить запрос. Как только запрос будет отправлен со стороны клиента, сервер ответит вам.
1. Когда вы запускаете сценарий на стороне сервера, он запускается и ждет, пока клиент не запустится.
2. Затем клиент подключается и вводит запрос в виде строки.
3. Когда клиент отправляет запрос, сервер отвечает.
Вот как вам нужно выполнить программу сокета на Java. Вы также можете запускать эти программы в окне терминала или в командной строке. Но, поскольку Eclipse хорошо расширен своими функциями, вы можете просто запустить обе программы на консоли.
Настройка проекта
Java предоставляет набор классов и интерфейсов, которые заботятся о деталях низкоуровневой связи между клиентом и сервером.
Они в основном содержатся в java.net пакет, поэтому нам нужно сделать следующий импорт:
import java.net.*;
Нам также нужны java.io пакет, который дает нам входные и выходные потоки для записи и чтения во время общения:
import java.io.*;
Для простоты мы запустим наши клиентские и серверные программы на одном компьютере. Если бы мы выполняли их на разных сетевых компьютерах, единственное, что изменилось бы, – это IP-адрес, в этом случае мы будем использовать localhost on 127.0.0.1 .
Бизнес-кейс
Чтобы быстро добавлять новые виджеты в биржевое приложение и подключать их без перераспределения всей платформы, нужно, чтобы они были автономными и управляли своим собственным механизмом ввода-вывода данных.
Виджеты никак не связаны друг с другом. В идеале они все должны быть подписаны на какую-либо конечную точку API и начинать получать данные от нее.
Но при этом число подключений будет увеличиваться с ростом количества виджетов. Поэтому необходимо установить ограничение для браузеров по количеству одновременно обрабатываемых HTTP-запросов.
Данные, которые получат виджеты, в основном состоят из чисел и обновлений для этих чисел: первоначальный ответ содержит 10 акций со значениями их котировок.
Также данные должны включать в себя возможность добавления / удаления торгуемых акций, а также обновление текущих котировок. Мы передаем небольшое количество JSON-строк для каждого обновления так быстро, как это возможно.
HTTP / 2 обеспечивает мультиплексирование запросов, поступающих от одного домена. То есть, мы можем получить одно соединение для нескольких ответов.
Начнем с изучения различных вариантов получения данных и посмотрим, что может дать каждый из них.
- Мы собираемся использовать NGINX для балансировки нагрузки и реализации прокси, чтобы скрыть все конечные точки за одним и тем же доменом.
- Мы хотим эффективно использовать сетевой трафик и потребление заряда батареи пользовательского устройства.
Заключение
SSE является решением наших проблем с доставкой данных. Попутно возникли и некоторые сложности, но они оказались простыми для исправления.
Вот как выглядит окончательная рабочая установка:
Обзор окончательной архитектуры. Все конечные точки API обслуживаются NGINX, поэтому клиенты получают мультиплексированный ответ.
NGINX дает нам следующее:
- Прокси-сервер для конечных точек API в разных местах;
- HTTP / 2 и все его преимущества, такие как мультиплексирование для соединений;
- Балансировка нагрузки;
- SSL.
Таким образом, мы управляем доставкой данных и сертификатами в одном месте, вместо того, чтобы делать это отдельно на каждой конечной точке.
Основные преимущества этого подхода:
- Эффективность данных;
- Упрощенная реализация;
- Соединения автоматически мультиплексируются через HTTP / 2;
- Механизм экономии заряда аккумулятора пользовательского устройства путем разгрузки соединения с прокси-сервером.
SSE позволяет обойтись без дополнительных затрат ресурсов, в отличие от альтернатив. Что касается серверной реализации, она не сильно отличается от поллинга. Но в клиенте все намного проще, чем при поллинге, поскольку для него требуется первоначальная подписка и назначение обработчиков событий. Это очень похоже на управление WebSockets.
Здесь вы можете найти демо-версию кода простой реализации клиента и сервера.
Пожалуйста, оставьте свои отзывы по текущей теме материала. За комментарии, отклики, подписки, дизлайки, лайки огромное вам спасибо!
Пожалуйста, опубликуйте ваши комментарии по текущей теме статьи. За комментарии, дизлайки, отклики, подписки, лайки низкий вам поклон!
Вадим Дворниковавтор-переводчик статьи «Using SSE Instead Of WebSockets For Unidirectional Data Flow Over HTTP/2»