在IOS中构建一个使用node.js服务器的聊天应用程序[关闭]
Posted
技术标签:
【中文标题】在IOS中构建一个使用node.js服务器的聊天应用程序[关闭]【英文标题】:Building a chat app that uses a node.js server in IOS [closed] 【发布时间】:2014-11-07 09:01:21 【问题描述】:我正在尝试在 socket.io 上构建一个使用 node.js 的 iPhone(本机)聊天应用程序。
在 ios 上创建聊天应用程序的最佳方法是什么
有没有办法在IOS中用node.js服务器创建聊天应用
谁能给我建议?
谢谢你的建议
【问题讨论】:
纯 FWIW。考虑只使用 pubnub(或者 parse.com + pubnub)。几行代码就可以搞定 @joe Blow: 可能是 parse.com + pubnub 的任何示例 嗨@btmanikandan,你在吗? 【参考方案1】:因为您可以使用带有 iOS/android 和 html 的 Socket.io 创建聊天应用程序!
有两种方法可以做到!
i) 用Socket.io实现自己的socket通信,(这个比较难,因为大部分网络实现需要自己写!)
Socket.io 将作为流接口,您需要从 iOS 连接!
您可以参考 iOS 开发指南了解如何实现流!
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/UsingSocketsandSocketStreams.html
也有一个活跃的线程在讨论这个问题!
iPhone Objective-C socket communication with Socket.IO
ii) 使用人们为 iOS 制作的现有库或包装器,您可以在下面找到链接!
这个库主要做了网络部分,你只需要实现你的应用逻辑!
iOS
https://github.com/pkyeck/socket.IO-objc
安卓
https://github.com/nkzawa/socket.io-client.java
最好先从库开始,然后尝试自己实现! :))
【讨论】:
github.com/shuoli84/SocketIOCocoa socketio 1.0 的快速客户端【参考方案2】:我建议如下:
-
在服务器上使用 node.js 和 NOSQL 数据库(在我的示例中为 CouchDb)开发 HTML5 应用程序
不要将 socket.io 用于您的第一个游乐场,因为它很复杂。您首先必须非常了解 websockets。
不要用预先准备好的框架和大量代码给自己带来负担。您需要一个清晰、简单的代码,以便进行以后需要的修改。您需要完全控制和理解您拥有的代码。
我附上了工作样本(感谢 Ales Smodis)。为了使下面的示例工作,您需要安装 2 个 node.js 数据包:
npm install websocket
npm install nano
您需要创建数据库并将至少 1 个用户插入 CouchDb 数据库:
curl -X PUT http://localhost:5984/chatroom
curl -X PUT -H 'Content-Type: application/json' --data '"username":"john","password":"john"' http://localhost:5984/chatroom/john
$(document).ready(function ()
var connection,
username = 'Tester',
password = 'Tester',
historyCounter = 0,
members = ,
// displays
jqLogin = $('#login'),
jqChatroom = $('#chatroom'),
// login display components
jqWaiting = $('#waiting'),
jqNickname = $('#nickname'),
jqPassword = $('#password'),
// chat display components
jqHistory = $('#history'),
jqMembers = $('#members'),
jqLine = $('#line');
function addLine(nick, line)
var jq = $('<p><span class="nick"></span><span class="line"></span></p>'),
jqNick = jq.find('.nick'),
jqLine = jq.find('.line'),
i, lines;
jqNick.text(nick ? nick + ': ' : '*** ');
jqLine.text(line);
jqHistory.append(jq);
historyCounter++;
for (lines = jqHistory.children(), i = 0; historyCounter > 100; i++, historyCounter--)
$(lines[i]).remove();
function addMsg(msgObj)
var msgHandler = states[activeState].messageHandlers[msgObj.type] || function () addLine(null, 'Neveljaven paket tipa ' + msgObj.type); ;
msgHandler(msgObj);
function clearMembers()
var nickname;
for (nickname in members)
members[nickname].remove();
delete members[nickname];
jqMembers.empty(); // just in case
function addMember(nickname)
var jq = $('<li></li>');
jq.text(nickname);
jqMembers.append(jq);
members[nickname] = jq;
function removeMember(nickname)
if (nickname in members)
members[nickname].remove();
delete members[nickname];
function connect ()
connection = new WebSocket('ws://127.0.0.1:8080');
connection.onopen = function ()
states[activeState].onopen();
;
connection.onmessage = function (message)
try
addMsg(JSON.parse(message.data));
catch (e)
addLine(null, 'Exception while handling a server message: ' + e.toString());
;
connection.onclose = function ()
states[activeState].onclose();
;
function loginKeypress(event)
if (13 !== event.keyCode) return;
username = jqNickname.val();
password = jqPassword.val();
if (!username) jqNickname[0].focus();
else if (!password) jqPassword[0].focus();
else
jqWaiting.css('display', '');
jqNickname.unbind('keydown', loginKeypress);
jqPassword.unbind('keydown', loginKeypress);
connect();
function inputKeypress(event)
var line;
if (13 === event.keyCode)
line = jqLine.val();
if (line.length === 0) return;
jqLine.val('');
connection.send(JSON.stringify( 'type': 'line', 'line': line ));
var states =
'login':
'start': function ()
jqChatroom.css('display', 'none');
jqWaiting.css('display', 'none');
jqLogin.css('display', '');
jqNickname.val('');
jqPassword.val('');
jqNickname[0].focus();
activeState = 'login';
jqNickname.bind('keydown', loginKeypress);
jqPassword.bind('keydown', loginKeypress);
,
'onopen': function ()
connection.send(JSON.stringify( 'type': 'login', 'username': username, 'password': password ));
,
'messageHandlers':
'state': function (msgObj)
var i, history, users;
states.chat.start();
history = msgObj.history;
jqHistory.empty();
historyCounter = 0;
for (i = 0; i < history.length; i++) addMsg(history[i]);
users = msgObj.users;
clearMembers();
for (i = 0; i < users.length; i++) addMember(users[i]);
,
'unhandledMessage': function (msgObj)
connection.close(4000, 'Unhandled message type');
,
'onclose': function ()
states.login.start();
,
'chat':
'start': function ()
jqLogin.css('display', 'none');
jqWaiting.css('display', 'none');
jqChatroom.css('display', '');
jqHistory.empty();
historyCounter = 0;
activeState = 'chat';
jqLine.bind('keydown', inputKeypress);
,
'onopen': function ()
connection.close(4001, 'Connection opened while chatting');
,
'messageHandlers':
'line': function (msgObj)
addLine(msgObj.nick, msgObj.line);
,
'join': function (msgObj)
addLine(null, 'Priklopil: ' + msgObj.nick);
addMember(msgObj.nick);
,
'leave': function (msgObj)
addLine(null, 'Odklopil: ' + msgObj.nick);
removeMember(msgObj.nick);
,
'unhandledMessage': function (msgObj)
connection.close(4000, 'Unhandled message type');
,
'onclose': function ()
addLine(null, 'Connection closed');
jqLine.unbind('keydown', inputKeypress);
,
activeState = 'login';
states.login.start();
);
// node.js code
var http = require('http'),
url = require('url'),
path = require('path'),
fs = require('fs'),
nano = require('nano')('http://localhost:5984'),
chatroomDb = nano.use('chatroom'),
websocket = require('websocket'),
chatHistory = [],
activeUsers = ;
var filesDir = path.join(process.cwd(), 'web');
var mimeTypes =
'.html': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript'
;
var getContentType = function (extension)
var mimeType = mimeTypes[extension];
return mimeType ? mimeType : 'application/octet-stream';
;
var server = http.createServer(function (request, response)
var relativePath = url.parse(request.url).pathname,
absolutePath = path.join(filesDir, relativePath);
var handler = function (err, stats)
if (stats)
if (stats.isDirectory())
absolutePath = path.join(absolutePath, 'index.html');
fs.stat(absolutePath, handler);
return;
if (stats.isFile())
response.writeHead(200, getContentType(path.extname(absolutePath)));
var stream = fs.createReadStream(absolutePath);
stream.pipe(response);
return;
response.writeHead(404, 'Content-Type': 'text/plain');
response.write('Not found\r\n');
response.end();
;
console.log('HTTP request for ' + relativePath);
fs.stat(absolutePath, handler);
);
server.listen(8080, function () );
wsServer = new websocket.server(
'httpServer': server
);
function addLine (type, nick, line)
var msg = 'type': type, 'nick': nick, 'line': line ,
jsonMsg = JSON.stringify(msg),
username;
chatHistory.push(msg);
while (chatHistory.length > 100) chatHistory.shift();
for (username in activeUsers)
activeUsers[username].sendMessage(jsonMsg);
wsServer.on('request', function (request)
console.log('New websocket connection from ' + request.origin);
// TODO: verify that request.origin is our web site
var connection = request.accept(null, request.origin);
var username = null;
connection.on('message', function (message)
if (message.type !== 'utf8')
console.log('Refusing a non-utf8 message');
return;
console.log('Processing message: ' + message.utf8Data);
try
var m = JSON.parse(message.utf8Data);
switch (m.type)
case 'login':
chatroomDb.get(m.username, function (err, body)
if (err || (body.password !== m.password))
connection.close();
return;
username = m.username;
addLine('join', username, null);
activeUsers[username] =
'sendMessage': function (jsonMsg)
connection.sendUTF(jsonMsg);
;
var users = [], u;
for (u in activeUsers) users.push(u);
connection.sendUTF(JSON.stringify( 'type': 'state', 'history': chatHistory, 'users': users ));
);
break;
case 'line':
if (!username)
connection.close();
break;
addLine('line', username, m.line);
break;
catch (e)
console.log(e);
);
connection.on('close', function (connection)
console.log('Connection closed');
if (username)
delete activeUsers[username];
addLine('leave', username, null);
);
);
console.log('Server running');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chatroom</title>
<style>
html, body
width: 100%;
height: 100%;
padding: 0;
border: none;
margin: 0;
#heading
position: absolute;
top: 0;
left: 0;
right: 0;
height: 30px;
margin: 0;
padding: 0;
line-height: 30px;
text-align: center;
font-size: 20px;
background-color: green;
#outer
position: absolute;
top: 30px;
bottom: 0;
left: 0;
right: 0;
margin: 20px;
min-height: 400px;
min-width: 400px;
background-color: lime;
#inner
height: 100%;
background-color: #ffc0cb;
#chat
position: absolute;
top: 0;
left: 0;
right: 200px;
bottom: 0;
background-color: #ffd700;
#members
position: absolute;
top: 0;
right: 10px;
width: 180px;
bottom: 0;
background-color: #ff00ff;
list-style-type: none;
padding: 10px;
padding: 0;
border: none;
#history
position: absolute;
top: 0;
left: 0;
bottom: 2em;
right: 0;
background-color: #00ffff;
padding: 10px;
#input
position: absolute;
height: 2em;
left: 0;
right: 0;
bottom: 0;
background-color: #90ee90;
line-height: 2em;
#line
width: 100%;
margin: 0;
border: none;
padding: 0;
#history > p
margin: 2px;
.nick
white-space: pre;
display: table-cell;
.line
display: table-cell;
#login
height: 100%;
display: table;
margin: 0 auto;
#login > .svg
vertical-align: middle;
display: table-cell;
#login-wrapper1
display: table;
height: 100%;
width: 100%;
#login-wrapper2
display: table-cell;
vertical-align: middle;
#login-table
margin: 0 auto;
#login-table .label
text-align: right;
#waiting
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: 0.3;
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="client.js"></script>
</head>
<body>
<div id="login">
<div class="svg">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 400 400"
>
<defs>
<path id="curved-text" d="M0,0 c 50 -50 150 -50 200 0" />
</defs>
<g>
<text
transform="translate(-100,40)"
font-weight="bold"
font-variant="small-caps"
font-family="Arial sans-serif"
font-size="30"
fill="none"
stroke="orange"
text-anchor="middle">
<textPath xlink:href="#curved-text" startOffset="50%">Chatroom</textPath>
</text>
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="360" dur="5s" fill="remove" additive="sum" repeatCount="indefinite" />
<animateMotion dur="10s" repeatCount="indefinite" path="M100,200 a100,100 0 1 1 200,0 a100,100 0 1 1 -200,0" />
</g>
<foreignObject
x="0"
y="0"
style="height:400px;">
<div xmlns="http://www.w3.org/1999/xhtml" id="login-wrapper1">
<div id="login-wrapper2">
<table id="login-table">
<tbody>
<tr>
<td class="label">Vzdevek:</td><td><input type="text" id="nickname" /></td>
</tr>
<tr>
<td class="label">Geslo:</td><td><input type="password" id="password" /></td>
</tr>
</tbody>
</table>
</div>
</div>
</foreignObject>
</svg>
</div>
</div>
<div id="chatroom" style="display:none;">
<h1 id="heading">Chatroom</h1>
<div id="outer">
<div id="inner">
<div id="chat">
<div id="history">
<p><span class="nick">Matej: </span><span class="line">Hi</span></p>
<p><span class="nick">Borut: </span><span class="line">How are you?</span></p>
<p><span class="nick">Martina: </span><span class="line">Ok, thanks!</span></p>
</div>
<div id="input"><input id="line" type="text"></div>
</div>
<ul id="members">
<li>Matej</li>
<li>Borut</li>
<li>Martina</li>
</ul>
</div>
</div>
</div>
<div id="waiting" style="display:none;"></div>
</body>
</html>
【讨论】:
【参考方案3】:如果您正在评估选项,请查看 Twilio 的 IP 消息:
https://www.twilio.com/docs/tutorials/walkthrough/ip-chat/ios/swift#0
上面的 Swift for iOS(也适用于 Objective-C)中的教程允许您在服务器端应用程序 (yours in Node.js) 生成用户访问令牌以连接到 API 时使用本机 SDK。
代码将引导您完成加入频道、创建频道和发送消息的过程。
注意:我确实为 Twilio 工作。这个快速示例应用程序至少应该可以帮助您确定最适合您的功能。
【讨论】:
以上是关于在IOS中构建一个使用node.js服务器的聊天应用程序[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Node.js笔记-使用socket.io构建websocket聊天室