如何显示通过 WebSocket 发送的 UTF-8 字符?

3
我正在尝试构建一个简单的WebSocket服务器,它加载包含一些推文的文件(格式为CSV),然后通过WebSocket将推文字符串发送到Web浏览器。 这里是我用于测试的示例。 这是 Autobahn 服务器组件 (server.py):
import random
import time
from twisted.internet   import reactor
from autobahn.websocket import WebSocketServerFactory, \
                               WebSocketServerProtocol, \
                               listenWS


f = open("C:/mypath/parsed_tweets_sample.csv")

class TweetStreamProtocol(WebSocketServerProtocol):

    def sendTweet(self):
        tweet = f.readline().split(",")[2]
        self.sendMessage(tweet, binary=False)

    def onMessage(self, msg, binary):
        self.sendTweet() 

if __name__ == '__main__':

   factory = WebSocketServerFactory("ws://localhost:9000", debug = False)
   factory.protocol = TweetStreamProtocol
   listenWS(factory)
   reactor.run()

以下是Web组件(index.html):

<html>
   <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <script type="text/javascript"> 
            var ws = new WebSocket("ws://localhost:9000");

            ws.onmessage = function(e) {
               document.getElementById('msg').textContent = e.data; //unescape(encodeURIComponent(e.data));
               console.log("Got echo: " + e.data);
            }
      </script>
   </head>
   <body>
      <h3>Twitter Stream Visualization</h3>
      <div id="msg"></div>
      <button onclick='ws.send("tweetme");'>
         Get Tweet
      </button>
   </body>
</html>

当推文在浏览器中到达时,UTF-8字符无法正确显示。我该如何修改这些简单的脚本,以在浏览器中显示正确的UTF-8字符?

也许你的默认字体没有你尝试显示的Unicode/UTF-8代码点? - kanaka
2
尝试使用self.sendMessage(u"\u03C0".encode("utf8"), binary = False),并检查浏览器中是否显示希腊字母"π"。 - oberstet
@oberstet 是的,这会被识别为 pi 字符。但是,如果我将该行切换为 self.sendMessage(tweet.encode("utf8"), binary=False),我会收到错误信息 exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 138: ordinal not in range(128) - Clay
2个回答

1
这对我有用:

这适用于我:

from autobahn.twisted.websocket import WebSocketServerProtocol, \
                                       WebSocketServerFactory


class TweetStreamProtocol(WebSocketServerProtocol):

   def sendTweets(self):
      for line in open('gistfile1.txt').readlines():
         ## decode UTF8 encoded file
         data = line.decode('utf8').split(',')

         ## now operate on data using Python string functions ..

         ## encode and send payload
         payload = data[2].encode('utf8')
         self.sendMessage(payload)

      self.sendMessage((u"\u03C0"*10).encode("utf8"))

   def onMessage(self, payload, isBinary):
      if payload == "tweetme":
         self.sendTweets()



if __name__ == '__main__':

   import sys

   from twisted.python import log
   from twisted.internet import reactor

   log.startLogging(sys.stdout)

   factory = WebSocketServerFactory("ws://localhost:9000", debug = False)
   factory.protocol = TweetStreamProtocol

   reactor.listenTCP(9000, factory)
   reactor.run()

注意:

  • 上面的代码适用于 Autobahn|Python 0.7 及以上版本
  • 我不确定你的示例 Gist 是否是正确的 UTF8 编码文件
  • 然而,“last”伪推文是10倍“pi”,在浏览器中显示正常,所以原则上它可以工作。

另请注意:由于原因太长无法在此解释,Autobahn 的 sendMessage 函数希望 payloadisBinary == False 的情况下已经是 UTF8 编码。一个“正常”的 Python 字符串是 Unicode,需要像上面那样编码为 UTF8 才能发送。


感谢提供代码。我认为源文件没有被错误编码,但我怀疑一些Unicode字符(我认为是UTF-8?)超出了UTF-8的正常字符映射。奇怪的是,当文件作为UTF-8导入Excel时,它们会显示,但通过Python导入时却无法显示。 - Clay
UTF8是Unicode的编码方式,它能够编码任何Unicode代码点。 - oberstet

0

不要使用 <meta http-equiv="content-type" content="text/html; charset=UTF-8"><,请尝试使用 <meta charset = utf-8>
如果您正在使用XHTML,请编写<meta charset = utf-8 />


谢谢。不过那似乎并没有什么帮助。 - Clay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接